You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2020/12/02 00:57:12 UTC

[servicecomb-service-center] branch master updated: [SCB-2094] implement mongo instance/dependence/engine interface (#759)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0c9258e  [SCB-2094] implement mongo instance/dependence/engine interface (#759)
0c9258e is described below

commit 0c9258e3761ba1838948c9a48bd3cfd12d8e5798
Author: xzccfzy <50...@users.noreply.github.com>
AuthorDate: Wed Dec 2 08:56:21 2020 +0800

    [SCB-2094] implement mongo instance/dependence/engine interface (#759)
---
 datasource/dependency_util.go                      |   47 +
 datasource/mongo/account.go                        |   11 +-
 datasource/mongo/client/common.go                  |    1 +
 datasource/mongo/client/mongo.go                   |   12 +-
 datasource/mongo/common.go                         |   34 +
 datasource/mongo/database.go                       |   61 +-
 datasource/mongo/dep.go                            |  340 ++++++-
 datasource/mongo/dep_test.go                       |  351 +++++++
 datasource/mongo/engine.go                         |  213 +++-
 datasource/mongo/heartbeat/common.go               |   25 +
 .../mongo/heartbeat/heartbeatchecker/heartbeat.go  |    6 +-
 .../heartbeat/heartbeatchecker/heartbeat_test.go   |   10 +-
 .../heartbeat/heartbeatchecker/heartbeatchecker.go |    5 +-
 .../heartbeatchecker/heartbeatchecker_test.go      |    2 +-
 datasource/mongo/heartbeat/manager.go              |    4 +-
 datasource/mongo/mongo.go                          |    4 +-
 datasource/mongo/ms.go                             | 1025 ++++++++++++++++++--
 datasource/mongo/ms_test.go                        |  626 +++++++++---
 datasource/mongo/{engine.go => util.go}            |   35 +-
 19 files changed, 2534 insertions(+), 278 deletions(-)

diff --git a/datasource/dependency_util.go b/datasource/dependency_util.go
new file mode 100644
index 0000000..c907f04
--- /dev/null
+++ b/datasource/dependency_util.go
@@ -0,0 +1,47 @@
+package datasource
+
+import (
+	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
+	"github.com/apache/servicecomb-service-center/pkg/log"
+	pb "github.com/go-chassis/cari/discovery"
+)
+
+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 BadParamsResponse(detailErr string) *pb.CreateDependenciesResponse {
+	log.Errorf(nil, "request params is invalid. %s", detailErr)
+	if len(detailErr) == 0 {
+		detailErr = "Request params is invalid."
+	}
+	return &pb.CreateDependenciesResponse{
+		Response: pb.CreateResponse(pb.ErrInvalidParams, detailErr),
+	}
+}
+
+func toString(in *pb.MicroServiceKey) string {
+	return path.GenerateProviderDependencyRuleKey(in.Tenant, in)
+}
diff --git a/datasource/mongo/account.go b/datasource/mongo/account.go
index feba2af..ff57904 100644
--- a/datasource/mongo/account.go
+++ b/datasource/mongo/account.go
@@ -19,7 +19,6 @@ package mongo
 
 import (
 	"context"
-	"errors"
 
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
@@ -34,7 +33,7 @@ import (
 func (ds *DataSource) CreateAccount(ctx context.Context, a *rbacframe.Account) error {
 	exist, err := ds.AccountExist(ctx, a.Name)
 	if err != nil {
-		log.Errorf(err, "can not save account info")
+		log.Error("can not save account info", err)
 		return err
 	}
 	if exist {
@@ -42,7 +41,7 @@ func (ds *DataSource) CreateAccount(ctx context.Context, a *rbacframe.Account) e
 	}
 	hash, err := bcrypt.GenerateFromPassword([]byte(a.Password), 14)
 	if err != nil {
-		log.Errorf(err, "pwd hash failed")
+		log.Error("pwd hash failed", err)
 		return err
 	}
 	a.Password = stringutil.Bytes2str(hash)
@@ -86,7 +85,7 @@ func (ds *DataSource) GetAccount(ctx context.Context, key string) (*rbacframe.Ac
 	var account rbacframe.Account
 	err = result.Decode(&account)
 	if err != nil {
-		log.Errorf(err, "Decode account failed: ")
+		log.Error("Decode account failed: ", err)
 		return nil, err
 	}
 	return &account, nil
@@ -106,7 +105,7 @@ func (ds *DataSource) ListAccount(ctx context.Context, key string) ([]*rbacframe
 		var account rbacframe.Account
 		err = cursor.Decode(&account)
 		if err != nil {
-			log.Errorf(err, "Decode account failed: ")
+			log.Error("Decode account failed: ", err)
 			break
 		}
 		accounts = append(accounts, &account)
@@ -142,7 +141,7 @@ func (ds *DataSource) UpdateAccount(ctx context.Context, key string, account *rb
 		return err
 	}
 	if result.ModifiedCount == 0 {
-		return errors.New("UpdateAccount: no data to update")
+		return ErrUpdateNodata
 	}
 	return nil
 }
diff --git a/datasource/mongo/client/common.go b/datasource/mongo/client/common.go
index a9b7f7d..e71706a 100644
--- a/datasource/mongo/client/common.go
+++ b/datasource/mongo/client/common.go
@@ -21,4 +21,5 @@ import (
 
 var (
 	ErrCollectionsNil = errors.New("collection is nil")
+	ErrOpenDbFailed   = errors.New("open db failed")
 )
diff --git a/datasource/mongo/client/mongo.go b/datasource/mongo/client/mongo.go
index eabdb7d..4be189a 100644
--- a/datasource/mongo/client/mongo.go
+++ b/datasource/mongo/client/mongo.go
@@ -17,7 +17,7 @@ package client
 
 import (
 	"context"
-	"errors"
+	"fmt"
 	"time"
 
 	"github.com/apache/servicecomb-service-center/pkg/gopool"
@@ -55,7 +55,7 @@ func GetMongoClient() *MongoClient {
 func NewMongoClient(config storage.Options) {
 	inst := &MongoClient{}
 	if err := inst.Initialize(config); err != nil {
-		log.Errorf(err, "failed to init mongodb")
+		log.Error("failed to init mongodb", err)
 		inst.err <- err
 	}
 	mc = inst
@@ -86,7 +86,7 @@ func (mc *MongoClient) Ready() <-chan struct{} {
 func (mc *MongoClient) Close() {
 	if mc.client != nil {
 		if err := mc.client.Disconnect(context.TODO()); err != nil {
-			log.Errorf(err, "[close mongo client] failed disconnect the mongo client")
+			log.Error("[close mongo client] failed disconnect the mongo client", err)
 		}
 	}
 }
@@ -107,7 +107,7 @@ func (mc *MongoClient) HealthCheck(ctx context.Context) {
 				if err == nil {
 					break
 				}
-				log.Errorf(err, "retry to connect to mongodb %s after %s", mc.dbconfig.URI, MongoCheckDelay)
+				log.Error(fmt.Sprintf("retry to connect to mongodb %s after %s", mc.dbconfig.URI, MongoCheckDelay), err)
 				select {
 				case <-ctx.Done():
 					mc.Close()
@@ -124,13 +124,13 @@ func (mc *MongoClient) newClient(ctx context.Context) (err error) {
 	mc.client, err = mongo.Connect(ctx, clientOptions)
 	if err != nil {
 		if derr := mc.client.Disconnect(ctx); derr != nil {
-			log.Errorf(derr, "[init mongo client] failed to disconnect mongo client ")
+			log.Error("[init mongo client] failed to disconnect mongo clients", derr)
 		}
 		return
 	}
 	mc.db = mc.client.Database(MongoDB)
 	if mc.db == nil {
-		return errors.New("open db failed")
+		return ErrOpenDbFailed
 	}
 	return nil
 }
diff --git a/datasource/mongo/common.go b/datasource/mongo/common.go
new file mode 100644
index 0000000..8cab32c
--- /dev/null
+++ b/datasource/mongo/common.go
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except request compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to request writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mongo
+
+import "errors"
+
+var (
+	ErrInvalidConsumer                      = errors.New("Invalid consumer")
+	ErrUpdateNodata                         = errors.New("UpdateAccount: no data to update")
+	ErrServiceFileLost                      = errors.New("service center service file lost")
+	ErrInvalidDomainProject                 = errors.New("invalid domainProject")
+	ErrNotAllowDeleteSC                     = errors.New("not allow to delete service center")
+	ErrDeleteSchemaFailed                   = errors.New("delete schema failed")
+	ErrInvalidParamBatchGetInstancesRequest = errors.New("invalid param BatchGetInstancesRequest")
+)
+
+func NewError(errInfo string, errMsg string) error {
+	return errors.New(errInfo + errMsg)
+}
diff --git a/datasource/mongo/database.go b/datasource/mongo/database.go
index 0dc96f3..3bfdf25 100644
--- a/datasource/mongo/database.go
+++ b/datasource/mongo/database.go
@@ -32,8 +32,6 @@ const (
 	AccountTokenExpirationTime = "tokenexpirationtime"
 	AccountCurrentPassword     = "currentpassword"
 	AccountStatus              = "status"
-	InstanceID                 = "instanceinfo.instanceid"
-	ServiceID                  = "instanceinfo.serviceid"
 	RefreshTime                = "refreshtime"
 )
 
@@ -43,36 +41,41 @@ const (
 	CollectionSchema   = "schema"
 	CollectionRule     = "rule"
 	CollectionInstance = "instance"
+	CollectionDep      = "dependency"
 )
 
 const (
+	DepsQueueUUID     = "0"
 	ErrorDuplicateKey = 11000
 )
 
 const (
-	Domain             = "domain"
-	Project            = "project"
-	ServiceTag         = "tags"
-	SchemaID           = "schemaid"
-	RuleServiceID      = "serviceid"
-	RuleRuleID         = "ruleinfo.ruleid"
-	SchemaServiceID    = "serviceid"
-	ServiceServiceID   = "serviceinfo.serviceid"
-	ServiceProperty    = "serviceinfo.properties"
-	ServiceModTime     = "serviceinfo.modtimestamp"
-	ServiceEnv         = "serviceinfo.environment"
-	ServiceAppID       = "serviceinfo.appid"
-	ServiceServiceName = "serviceinfo.servicename"
-	ServiceAlias       = "serviceinfo.alias"
-	ServiceVersion     = "serviceinfo.version"
-	ServiceSchemas     = "serviceinfo.schemas"
-	RuleAttribute      = "ruleinfo.attribute"
-	RulePattern        = "ruleinfo.pattern"
-	RuleModTime        = "ruleinfo.modtimestamp"
-	RuleDescription    = "ruleinfo.description"
-	RuleRuletype       = "ruleinfo.ruletype"
-	SchemaInfo         = "schemainfo"
-	SchemaSummary      = "schemasummary"
+	ColumnDomain         = "domain"
+	ColumnProject        = "project"
+	ColumnTag            = "tags"
+	ColumnSchemaID       = "schemaid"
+	ColumnServiceID      = "serviceid"
+	ColumnRuleID         = "ruleid"
+	ColumnServiceInfo    = "serviceinfo"
+	ColumnProperty       = "properties"
+	ColumnModTime        = "modtimestamp"
+	ColumnEnv            = "environment"
+	ColumnAppID          = "appid"
+	ColumnServiceName    = "servicename"
+	ColumnAlias          = "alias"
+	ColumnVersion        = "version"
+	ColumnSchemas        = "schemas"
+	ColumnAttribute      = "attribute"
+	ColumnPattern        = "pattern"
+	ColumnDescription    = "description"
+	ColumnRuleType       = "ruletype"
+	ColumnSchemaInfo     = "schemainfo"
+	ColumnSchemaSummary  = "schemasummary"
+	ColumnConsumer       = "consumer"
+	ColumnDependencyInfo = "dependencyinfo"
+	ColumnRuleInfo       = "ruleinfo"
+	ColumnInstanceInfo   = "instanceinfo"
+	ColumnInstanceID     = "instanceid"
 )
 
 type Service struct {
@@ -104,3 +107,11 @@ type Instance struct {
 	RefreshTime  time.Time
 	InstanceInfo *pb.MicroServiceInstance
 }
+
+type Dependency struct {
+	Domain         string
+	Project        string
+	ConsumerID     string
+	UUID           string
+	DependencyInfo *pb.ConsumerDependency
+}
diff --git a/datasource/mongo/dep.go b/datasource/mongo/dep.go
index e3322a2..6a1eef2 100644
--- a/datasource/mongo/dep.go
+++ b/datasource/mongo/dep.go
@@ -21,20 +21,354 @@ import (
 	"context"
 
 	pb "github.com/go-chassis/cari/discovery"
+	"go.mongodb.org/mongo-driver/bson"
+
+	"fmt"
+	"strings"
+
+	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
+	"github.com/apache/servicecomb-service-center/pkg/log"
+	"github.com/apache/servicecomb-service-center/pkg/util"
 )
 
 func (ds *DataSource) SearchProviderDependency(ctx context.Context, request *pb.GetDependenciesRequest) (*pb.GetProDependenciesResponse, error) {
-	return &pb.GetProDependenciesResponse{}, nil
+	providerServiceID := request.ServiceId
+	filter := GeneratorServiceFilter(ctx, providerServiceID)
+	provider, err := GetService(ctx, filter)
+	if err != nil {
+		log.Error("GetProviderDependencies failed, provider is "+providerServiceID, err)
+		return nil, err
+	}
+	if provider == nil {
+		log.Error(fmt.Sprintf("GetProviderDependencies failed for provider %s", providerServiceID), err)
+		return &pb.GetProDependenciesResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, "Provider does not exist"),
+		}, nil
+	}
+
+	services, err := GetDependencyProviders(ctx, provider.ServiceInfo, request)
+	if err != nil {
+		log.Error(fmt.Sprintf("GetProviderDependencies failed, provider is %s/%s/%s/%s",
+			provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version), err)
+		return &pb.GetProDependenciesResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+
+	return &pb.GetProDependenciesResponse{
+		Response:  pb.CreateResponse(pb.ResponseSuccess, "Get all consumers successful."),
+		Consumers: services,
+	}, nil
 }
 
 func (ds *DataSource) SearchConsumerDependency(ctx context.Context, request *pb.GetDependenciesRequest) (*pb.GetConDependenciesResponse, error) {
-	return &pb.GetConDependenciesResponse{}, nil
+	consumerID := request.ServiceId
+
+	filter := GeneratorServiceFilter(ctx, consumerID)
+	consumer, err := GetService(ctx, filter)
+	if err != nil {
+		log.Error(fmt.Sprintf("GetConsumerDependencies failed, consumer is %s", consumerID), err)
+		return nil, err
+	}
+	if consumer == nil {
+		log.Error(fmt.Sprintf("GetConsumerDependencies failed for consumer %s does not exist", consumerID), err)
+		return &pb.GetConDependenciesResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, "Consumer does not exist"),
+		}, nil
+	}
+
+	services, err := GetDependencyProviders(ctx, consumer.ServiceInfo, request)
+	if err != nil {
+		log.Error(fmt.Sprintf("GetConsumerDependencies failed, consumer is %s/%s/%s/%s",
+			consumer.ServiceInfo.Environment, consumer.ServiceInfo.AppId, consumer.ServiceInfo.ServiceName, consumer.ServiceInfo.Version), err)
+		return &pb.GetConDependenciesResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+
+	return &pb.GetConDependenciesResponse{
+		Response:  pb.CreateResponse(pb.ResponseSuccess, "Get all providers successfully."),
+		Providers: services,
+	}, nil
 }
 
 func (ds *DataSource) AddOrUpdateDependencies(ctx context.Context, dependencyInfos []*pb.ConsumerDependency, override bool) (*pb.Response, error) {
-	return pb.CreateResponse(pb.ResponseSuccess, ""), nil
+	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 := 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), err)
+			return pb.CreateResponse(pb.ErrServiceNotExists, fmt.Sprintf("Consumer %s does not exist.", consumerFlag)), nil
+		}
+
+		dependencyInfo.Override = override
+		id := DepsQueueUUID
+		if !override {
+			id = util.GenerateUUID()
+		}
+
+		domain := util.ParseDomain(ctx)
+		project := util.ParseProject(ctx)
+		data := &Dependency{
+			Domain:         domain,
+			Project:        project,
+			ConsumerID:     consumerID,
+			UUID:           id,
+			DependencyInfo: dependencyInfo,
+		}
+		insertRes, err := client.GetMongoClient().Insert(ctx, CollectionDep, data)
+		if err != nil {
+			log.Error("failed to insert dep to mongodb", err)
+			return pb.CreateResponse(pb.ErrInternal, err.Error()), err
+		}
+		log.Error(fmt.Sprintf("insert dep to mongodb success %s", insertRes.InsertedID), err)
+	}
+	return pb.CreateResponse(pb.ResponseSuccess, "Create dependency successfully."), nil
 }
 
 func (ds *DataSource) DeleteDependency() {
 	panic("implement me")
 }
+
+func GetDependencyProviders(ctx context.Context, consumer *pb.MicroService, request *pb.GetDependenciesRequest) ([]*pb.MicroService, error) {
+	keys, err := GetProviderKeys(ctx, consumer)
+	if err != nil {
+		return nil, err
+	}
+
+	services := make([]*pb.MicroService, 0, len(keys))
+
+	for _, key := range keys {
+		domainProject := util.ParseDomainProject(ctx)
+		if request.SameDomain && key.Tenant != domainProject {
+			continue
+		}
+
+		providerIDs, err := ParseDependencyRule(ctx, key)
+		if err != nil {
+			return nil, err
+		}
+
+		if key.ServiceName == "*" {
+			services = services[:0]
+		}
+
+		for _, providerID := range providerIDs {
+			filter := GeneratorServiceFilter(ctx, providerID)
+			provider, err := GetService(ctx, filter)
+			if err != nil {
+				log.Warn(fmt.Sprintf("get provider[%s/%s/%s/%s] failed",
+					key.Environment, key.AppId, key.ServiceName, key.Version))
+				continue
+			}
+			if provider == nil {
+				log.Warn(fmt.Sprintf("provider[%s/%s/%s/%s] does not exist",
+					key.Environment, key.AppId, key.ServiceName, key.Version))
+				continue
+			}
+			if request.NoSelf && providerID == consumer.ServiceId {
+				continue
+			}
+			services = append(services, provider.ServiceInfo)
+		}
+
+		if key.ServiceName == "*" {
+			break
+		}
+	}
+
+	return services, nil
+}
+
+func GetProviderKeys(ctx context.Context, consumer *pb.MicroService) ([]*pb.MicroServiceKey, error) {
+	if consumer == nil {
+		return nil, ErrInvalidConsumer
+	}
+	domainProject := util.ParseDomainProject(ctx)
+	consumerMicroServiceKey := &pb.MicroServiceKey{
+		Tenant:      domainProject,
+		Environment: consumer.Environment,
+		AppId:       consumer.AppId,
+		ServiceName: consumer.ServiceName,
+		Alias:       consumer.Alias,
+		Version:     consumer.Version,
+	}
+
+	filter := GenerateConsumerDependencyRuleKey(ctx, consumerMicroServiceKey)
+
+	findRes, err := client.GetMongoClient().Find(ctx, CollectionDep, filter)
+	if err != nil {
+		return nil, err
+	}
+	var services []*pb.MicroServiceKey
+	for findRes.Next(ctx) {
+		var tempMongoDep Dependency
+		err := findRes.Decode(&tempMongoDep)
+		if err != nil {
+			return nil, err
+		}
+		providers := tempMongoDep.DependencyInfo.Providers
+		services = append(services, providers...)
+	}
+	return services, nil
+}
+
+func GenerateConsumerDependencyRuleKey(ctx context.Context, in *pb.MicroServiceKey) bson.M {
+
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	if in == nil {
+		return bson.M{
+			ColumnDomain:  domain,
+			ColumnProject: project,
+		}
+	}
+	if in.ServiceName == "*" {
+		return bson.M{
+			ColumnDomain:  domain,
+			ColumnProject: project,
+			StringBuilder([]string{ColumnDependencyInfo, ColumnConsumer, ColumnEnv}): in.Environment,
+		}
+	}
+	return bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnDependencyInfo, ColumnConsumer, ColumnEnv}):     in.Environment,
+		StringBuilder([]string{ColumnDependencyInfo, ColumnConsumer, ColumnAppID}):   in.AppId,
+		StringBuilder([]string{ColumnDependencyInfo, ColumnConsumer, ColumnVersion}): in.Version,
+	}
+}
+
+func ParseDependencyRule(ctx context.Context, dependencyRule *pb.MicroServiceKey) (serviceIDs []string, err error) {
+	switch {
+	case dependencyRule.ServiceName == "*":
+		splited := strings.Split(dependencyRule.Tenant, "/")
+		filter := bson.M{
+			ColumnDomain:  splited[0],
+			ColumnProject: splited[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}): dependencyRule.Environment}
+		findRes, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+		if err != nil {
+			return nil, err
+		}
+		for findRes.Next(ctx) {
+			var service Service
+			err = findRes.Decode(&service)
+			if err != nil {
+				return nil, err
+			}
+			serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+		}
+	default:
+		serviceIDs, err = FindServiceIds(ctx, dependencyRule)
+	}
+	return
+}
+
+func FindServiceIds(ctx context.Context, key *pb.MicroServiceKey) ([]string, error) {
+	versionRule := key.Version
+	splited := strings.Split(key.Tenant, "/")
+	if len(versionRule) == 0 {
+		return nil, nil
+	}
+	rangeIdx := strings.Index(versionRule, "-")
+	switch {
+	case versionRule == "latest":
+		filter := bson.M{
+			ColumnDomain:  splited[0],
+			ColumnProject: splited[1]}
+		return GetFilterVersionService(ctx, filter)
+	case versionRule[len(versionRule)-1:] == "+":
+		start := versionRule[:len(versionRule)-1]
+		filter := bson.M{
+			ColumnDomain:  splited[0],
+			ColumnProject: splited[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): bson.M{"$gte": start}}
+		return GetFilterVersionService(ctx, filter)
+	case rangeIdx > 0:
+		start := versionRule[:rangeIdx]
+		end := versionRule[rangeIdx+1:]
+		filter := bson.M{
+			ColumnDomain:  splited[0],
+			ColumnProject: splited[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): bson.M{"$gts": start, "$lt": end}}
+		return GetFilterVersionService(ctx, filter)
+	default:
+		filter := bson.M{
+			ColumnDomain:  splited[0],
+			ColumnProject: splited[1],
+			StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+			StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+			StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+			StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+		return GetFilterVersionService(ctx, filter)
+	}
+}
+
+func GetFilterVersionService(ctx context.Context, m bson.M) (serviceIDs []string, err error) {
+	findRes, err := client.GetMongoClient().Find(ctx, CollectionService, m)
+	if err != nil {
+		return nil, err
+	}
+	for findRes.Next(ctx) {
+		var service Service
+		err = findRes.Decode(&service)
+		if err != nil {
+			return nil, err
+		}
+		serviceIDs = append(serviceIDs, service.ServiceInfo.ServiceId)
+	}
+	return
+}
+
+func GetServiceID(ctx context.Context, key *pb.MicroServiceKey) (serviceID string, err error) {
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         key.Environment,
+		StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       key.AppId,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): key.ServiceName,
+		StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     key.Version}
+
+	findRes, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return "", nil
+	}
+	var service []*Service
+	for findRes.Next(ctx) {
+		var temp *Service
+		err := findRes.Decode(&temp)
+		if err != nil {
+			return "", nil
+		}
+		service = append(service, temp)
+	}
+	if service == nil {
+		return "", nil
+	}
+	return service[0].ServiceInfo.ServiceId, nil
+}
diff --git a/datasource/mongo/dep_test.go b/datasource/mongo/dep_test.go
new file mode 100644
index 0000000..77bdc06
--- /dev/null
+++ b/datasource/mongo/dep_test.go
@@ -0,0 +1,351 @@
+/*
+* 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 mongo_test
+
+import (
+	"testing"
+
+	"github.com/apache/servicecomb-service-center/datasource"
+	pb "github.com/go-chassis/cari/discovery"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestDep_Creat(t *testing.T) {
+
+	var (
+		consumerId1 string
+		consumerId3 string
+	)
+
+	t.Run("creat service, when request is valid, should not pass", func(t *testing.T) {
+		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep1",
+				AppId:       "create_dep_group",
+				ServiceName: "create_dep_consumer",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		consumerId1 = respCreateService.ServiceId
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep2",
+				AppId:       "create_dep_group",
+				ServiceName: "create_dep_consumer_all",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		consumerId3 = respCreateService.ServiceId
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep3",
+				Environment: pb.ENV_PROD,
+				AppId:       "create_dep_group",
+				ServiceName: "create_dep_consumer",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep4",
+				AppId:       "create_dep_group",
+				ServiceName: "create_dep_provider",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep5",
+				AppId:       "create_dep_group",
+				ServiceName: "create_dep_provider",
+				Version:     "1.0.1",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep6",
+				Environment: pb.ENV_PROD,
+				AppId:       "create_dep_group",
+				ServiceName: "create_dep_provider",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	})
+
+	t.Run("create dep, when request is valid, should be passed", func(t *testing.T) {
+
+		respCreateDependency, err := datasource.Instance().AddOrUpdateDependencies(getContext(), []*pb.ConsumerDependency{
+			{
+				Consumer: &pb.MicroServiceKey{
+					ServiceName: "create_dep_consumer",
+					AppId:       "create_dep_group",
+					Version:     "1.0.0",
+				},
+				Providers: []*pb.MicroServiceKey{
+					{
+						AppId:       "create_dep_group",
+						ServiceName: "create_dep_provider",
+						Version:     "latest",
+					},
+				},
+			},
+		}, false)
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateDependency.GetCode())
+
+		respPro, err := datasource.Instance().SearchConsumerDependency(getContext(), &pb.GetDependenciesRequest{
+			ServiceId: consumerId1,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respPro.Response.GetCode())
+		assert.NotEqual(t, "1.0.1", respPro.Providers[0].Version)
+
+		respCreateDependency, err = datasource.Instance().AddOrUpdateDependencies(getContext(), []*pb.ConsumerDependency{
+			{
+				Consumer: &pb.MicroServiceKey{
+					ServiceName: "create_dep_consumer",
+					AppId:       "create_dep_group",
+					Version:     "1.0.0",
+				},
+				Providers: []*pb.MicroServiceKey{
+					{
+						AppId:       "create_dep_group",
+						ServiceName: "create_dep_provider",
+						Version:     "1.0.0+",
+					},
+				},
+			},
+		}, false)
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateDependency.GetCode())
+
+		respPro, err = datasource.Instance().SearchConsumerDependency(getContext(), &pb.GetDependenciesRequest{
+			ServiceId: consumerId1,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respPro.Response.GetCode())
+		assert.NotEqual(t, "1.0.1", respPro.Providers[0].Version)
+
+		respCreateDependency, err = datasource.Instance().AddOrUpdateDependencies(getContext(), []*pb.ConsumerDependency{
+			{
+				Consumer: &pb.MicroServiceKey{
+					ServiceName: "create_dep_consumer",
+					AppId:       "create_dep_group",
+					Version:     "1.0.0",
+				},
+				Providers: []*pb.MicroServiceKey{
+					{
+						AppId:       "create_dep_group",
+						ServiceName: "create_dep_provider",
+						Version:     "1.0.0+",
+					},
+				},
+			},
+		}, false)
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateDependency.GetCode())
+
+		respPro, err = datasource.Instance().SearchConsumerDependency(getContext(), &pb.GetDependenciesRequest{
+			ServiceId: consumerId1,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respPro.Response.GetCode())
+		assert.NotEqual(t, 2, len(respPro.Providers))
+
+		respCreateDependency, err = datasource.Instance().AddOrUpdateDependencies(getContext(), []*pb.ConsumerDependency{
+			{
+				Consumer: &pb.MicroServiceKey{
+					ServiceName: "create_dep_consumer_all",
+					AppId:       "create_dep_group",
+					Version:     "1.0.0",
+				},
+				Providers: []*pb.MicroServiceKey{
+					{
+						ServiceName: "*",
+					},
+				},
+			},
+		}, false)
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateDependency.GetCode())
+
+		respPro, err = datasource.Instance().SearchConsumerDependency(getContext(), &pb.GetDependenciesRequest{
+			ServiceId: consumerId3,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respPro.Response.GetCode())
+		assert.NotEqual(t, 0, len(respPro.Providers))
+
+		respCreateDependency, err = datasource.Instance().AddOrUpdateDependencies(getContext(), []*pb.ConsumerDependency{
+			{
+				Consumer: &pb.MicroServiceKey{
+					ServiceName: "create_dep_consumer_all",
+					AppId:       "create_dep_group",
+					Version:     "1.0.0",
+				},
+				Providers: nil,
+			},
+		}, false)
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateDependency.GetCode())
+
+		respCreateDependency, err = datasource.Instance().AddOrUpdateDependencies(getContext(), []*pb.ConsumerDependency{
+			{
+				Consumer: &pb.MicroServiceKey{
+					ServiceName: "create_dep_consumer",
+					AppId:       "create_dep_group",
+					Version:     "1.0.0",
+				},
+				Providers: []*pb.MicroServiceKey{
+					{
+						AppId:       "create_dep_group",
+						ServiceName: "create_dep_provider",
+						Version:     "1.0.0",
+					},
+					{
+						ServiceName: "*",
+					},
+				},
+			},
+		}, false)
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateDependency.GetCode())
+
+		respCreateDependency, err = datasource.Instance().AddOrUpdateDependencies(getContext(), []*pb.ConsumerDependency{
+			{
+				Consumer: &pb.MicroServiceKey{
+					ServiceName: "create_dep_consumer",
+					AppId:       "create_dep_group",
+					Version:     "1.0.0",
+				},
+				Providers: []*pb.MicroServiceKey{
+					{
+						AppId:       "create_dep_group",
+						ServiceName: "create_dep_provider",
+						Version:     "1.0.0-1.0.1",
+					},
+				},
+			},
+		}, false)
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateDependency.GetCode())
+
+		respPro, err = datasource.Instance().SearchConsumerDependency(getContext(), &pb.GetDependenciesRequest{
+			ServiceId: consumerId1,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respPro.Response.GetCode())
+		assert.Equal(t, "1.0.0", respPro.Providers[0].Version)
+	})
+}
+
+func TestDep_Get(t *testing.T) {
+
+	var (
+		consumerId1 string
+		providerId1 string
+	)
+
+	t.Run("create service, when request is valid, should be passed", func(t *testing.T) {
+		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep7",
+				AppId:       "get_dep_group",
+				ServiceName: "get_dep_consumer",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		consumerId1 = respCreateService.ServiceId
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep8",
+				AppId:       "get_dep_group",
+				ServiceName: "get_dep_provider",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		providerId1 = respCreateService.ServiceId
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "dep9",
+				AppId:       "get_dep_group",
+				ServiceName: "get_dep_provider",
+				Version:     "2.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	})
+
+	t.Run("execute 'search dep' operation, when request is valid,should be passed", func(t *testing.T) {
+		respPro, err := datasource.Instance().SearchProviderDependency(getContext(), &pb.GetDependenciesRequest{
+			ServiceId: providerId1,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respPro.Response.GetCode())
+
+		respCon, err := datasource.Instance().SearchConsumerDependency(getContext(), &pb.GetDependenciesRequest{
+			ServiceId: consumerId1,
+		})
+
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCon.Response.GetCode())
+
+	})
+}
diff --git a/datasource/mongo/engine.go b/datasource/mongo/engine.go
index 246ce78..e7b799a 100644
--- a/datasource/mongo/engine.go
+++ b/datasource/mongo/engine.go
@@ -22,17 +22,114 @@ import (
 	"time"
 
 	"github.com/apache/servicecomb-service-center/pkg/cluster"
+
+	"fmt"
+	"strconv"
+	"strings"
+
+	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/etcd/path"
+	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
+	"github.com/apache/servicecomb-service-center/pkg/log"
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	"github.com/apache/servicecomb-service-center/server/core"
+	"github.com/apache/servicecomb-service-center/server/metrics"
+	pb "github.com/go-chassis/cari/discovery"
+	"go.mongodb.org/mongo-driver/bson"
 )
 
 func (ds *DataSource) SelfRegister(ctx context.Context) error {
-	return nil
+	err := ds.registryService(ctx)
+	if err != nil {
+		return err
+	}
+
+	// 实例信息
+	err = ds.registryInstance(ctx)
+
+	// wait heartbeat
+	ds.autoSelfHeartBeat()
+
+	metrics.ReportScInstance()
+	return err
 }
 func (ds *DataSource) SelfUnregister(ctx context.Context) error {
+	if len(core.Instance.InstanceId) == 0 {
+		return nil
+	}
+
+	ctx = core.AddDefaultContextValue(ctx)
+	respI, err := datasource.Instance().UnregisterInstance(ctx, core.UnregisterInstanceRequest())
+	if err != nil {
+		log.Error("unregister failed", err)
+		return err
+	}
+	if respI.Response.GetCode() != pb.ResponseSuccess {
+		err = fmt.Errorf("unregister service center instance[%s/%s] failed, %s",
+			core.Instance.ServiceId, core.Instance.InstanceId, respI.Response.GetMessage())
+		log.Error(err.Error(), nil)
+		return err
+	}
+	log.Warn(fmt.Sprintf("unregister service center instance[%s/%s]",
+		core.Service.ServiceId, core.Instance.InstanceId))
 	return nil
 }
 
 // OPS
 func (ds *DataSource) ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error {
+	services, err := GetAllServicesAcrossDomainProject(ctx)
+	if err != nil {
+		return err
+	}
+	if len(services) == 0 {
+		log.Info("no service found, no need to clear")
+		return nil
+	}
+
+	timeLimit := time.Now().Add(0 - ttl)
+	log.Info(fmt.Sprintf("clear no-instance services created before %s", timeLimit))
+	timeLimitStamp := strconv.FormatInt(timeLimit.Unix(), 10)
+
+	for domainProject, svcList := range services {
+		if len(svcList) == 0 {
+			continue
+		}
+		ctx, err := ctxFromDomainProject(ctx, domainProject)
+		if err != nil {
+			log.Error("get domain project context failed", err)
+			continue
+		}
+		for _, svc := range svcList {
+			if svc == nil {
+				continue
+			}
+			ok, err := shouldClear(ctx, timeLimitStamp, svc)
+			if err != nil {
+				log.Error("check service clear necessity failed", err)
+				continue
+			}
+			if !ok {
+				continue
+			}
+			svcCtxStr := "domainProject: " + domainProject + ", " +
+				"env: " + svc.Environment + ", " +
+				"service: " + util.StringJoin([]string{svc.AppId, svc.ServiceName, svc.Version}, path.SPLIT)
+			delSvcReq := &pb.DeleteServiceRequest{
+				ServiceId: svc.ServiceId,
+				Force:     true, //force delete
+			}
+			delSvcResp, err := datasource.Instance().UnregisterService(ctx, delSvcReq)
+			if err != nil {
+				log.Error(fmt.Sprintf("clear service failed, %s", svcCtxStr), err)
+				continue
+			}
+			if delSvcResp.Response.GetCode() != pb.ResponseSuccess {
+				log.Error(fmt.Sprintf("clear service failed %s %s", delSvcResp.Response.GetMessage(), svcCtxStr), err)
+				continue
+			}
+			log.Warn(fmt.Sprintf("clear service success, %s", svcCtxStr))
+		}
+	}
 	return nil
 }
 
@@ -43,3 +140,117 @@ func (ds *DataSource) UpgradeVersion(ctx context.Context) error {
 func (ds *DataSource) GetClusters(ctx context.Context) (cluster.Clusters, error) {
 	return nil, nil
 }
+
+func (ds *DataSource) registryService(pCtx context.Context) error {
+	ctx := core.AddDefaultContextValue(pCtx)
+	respE, err := datasource.Instance().ExistService(ctx, core.GetExistenceRequest())
+	if err != nil {
+		log.Error("query service center existence failed", err)
+		return err
+	}
+	if respE.Response.GetCode() == pb.ResponseSuccess {
+		log.Warn(fmt.Sprintf("service center service[%s] already registered", respE.ServiceId))
+		respG, err := datasource.Instance().GetService(ctx, core.GetServiceRequest(respE.ServiceId))
+		if respG.Response.GetCode() != pb.ResponseSuccess {
+			log.Error(fmt.Sprintf("query service center service[%s] info failed", respE.ServiceId), err)
+			return ErrServiceFileLost
+		}
+		core.Service = respG.Service
+		return nil
+	}
+
+	respS, err := datasource.Instance().RegisterService(ctx, core.CreateServiceRequest())
+	if err != nil {
+		log.Error("register service center failed", err)
+		return err
+	}
+	core.Service.ServiceId = respS.ServiceId
+	log.Info(fmt.Sprintf("register service center service[%s]", respS.ServiceId))
+	return nil
+}
+
+func (ds *DataSource) registryInstance(pCtx context.Context) error {
+	core.Instance.InstanceId = ""
+	core.Instance.ServiceId = core.Service.ServiceId
+
+	ctx := core.AddDefaultContextValue(pCtx)
+
+	respI, err := datasource.Instance().RegisterInstance(ctx, core.RegisterInstanceRequest())
+	if err != nil {
+		log.Error("register failed", err)
+		return err
+	}
+	if respI.Response.GetCode() != pb.ResponseSuccess {
+		err = fmt.Errorf("register service center[%s] instance failed, %s",
+			core.Instance.ServiceId, respI.Response.GetMessage())
+		log.Error(err.Error(), nil)
+		return err
+	}
+	core.Instance.InstanceId = respI.InstanceId
+	log.Info(fmt.Sprintf("register service center instance[%s/%s], endpoints is %s",
+		core.Service.ServiceId, respI.InstanceId, core.Instance.Endpoints))
+	return nil
+}
+
+func (ds *DataSource) autoSelfHeartBeat() {
+	//todo
+}
+
+func GetAllServicesAcrossDomainProject(ctx context.Context) (map[string][]*pb.MicroService, error) {
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+
+	filter := bson.M{"domain": domain, "project": project}
+
+	findRes, err := client.GetMongoClient().Find(ctx, CollectionService, filter)
+	if err != nil {
+		return nil, err
+	}
+
+	services := make(map[string][]*pb.MicroService)
+
+	for findRes.Next(ctx) {
+		var mongoService Service
+		err := findRes.Decode(&mongoService)
+		if err != nil {
+			return nil, err
+		}
+		domainProject := mongoService.Domain + "/" + mongoService.Project
+		services[domainProject] = append(services[domainProject], mongoService.ServiceInfo)
+	}
+	return services, nil
+}
+
+func ctxFromDomainProject(pCtx context.Context, domainProject string) (ctx context.Context, err error) {
+	splitIndex := strings.Index(domainProject, path.SPLIT)
+	if splitIndex == -1 {
+		return nil, NewError("invalid domainProject: ", domainProject)
+	}
+	domain := domainProject[:splitIndex]
+	project := domainProject[splitIndex+1:]
+	return util.SetDomainProject(pCtx, domain, project), nil
+}
+
+func shouldClear(ctx context.Context, timeLimitStamp string, svc *pb.MicroService) (bool, error) {
+	if svc.Timestamp > timeLimitStamp {
+		return false, nil
+	}
+
+	getInstsReq := &pb.GetInstancesRequest{
+		ConsumerServiceId: svc.ServiceId,
+		ProviderServiceId: svc.ServiceId,
+	}
+
+	getInstsResp, err := datasource.Instance().GetInstances(ctx, getInstsReq)
+	if err != nil {
+		return false, err
+	}
+	if getInstsResp.Response.GetCode() != pb.ResponseSuccess {
+		return false, NewError("get instance failed: ", getInstsResp.Response.GetMessage())
+	}
+	//ignore a service if it has instances
+	if len(getInstsResp.Instances) > 0 {
+		return false, nil
+	}
+	return true, nil
+}
diff --git a/datasource/mongo/heartbeat/common.go b/datasource/mongo/heartbeat/common.go
new file mode 100644
index 0000000..9d5cb31
--- /dev/null
+++ b/datasource/mongo/heartbeat/common.go
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except request compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to request writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package heartbeat
+
+import "errors"
+
+var (
+	ErrPluginNameNil    = errors.New("plugin implement name is nil")
+	ErrPluginNotSupport = errors.New("plugin implement not supported [#{opts.PluginImplName}]")
+)
diff --git a/datasource/mongo/heartbeat/heartbeatchecker/heartbeat.go b/datasource/mongo/heartbeat/heartbeatchecker/heartbeat.go
index f87d08c..57e50f0 100644
--- a/datasource/mongo/heartbeat/heartbeatchecker/heartbeat.go
+++ b/datasource/mongo/heartbeat/heartbeatchecker/heartbeat.go
@@ -29,15 +29,15 @@ import (
 
 func updateInstanceRefreshTime(ctx context.Context, serviceID string, instanceID string) error {
 	filter := bson.M{
-		mongo.InstanceID: instanceID,
-		mongo.ServiceID:  serviceID,
+		mongo.StringBuilder([]string{mongo.ColumnInstanceInfo, mongo.ColumnInstanceID}): instanceID,
+		mongo.StringBuilder([]string{mongo.ColumnInstanceInfo, mongo.ColumnServiceID}):  serviceID,
 	}
 	update := bson.M{
 		"$set": bson.M{mongo.RefreshTime: time.Now()},
 	}
 	result, err := client.GetMongoClient().FindOneAndUpdate(ctx, mongo.CollectionInstance, filter, update)
 	if err != nil {
-		log.Errorf(err, "failed to update refresh time of instance: ")
+		log.Error("failed to update refresh time of instance: ", err)
 		return err
 	}
 	if result.Err() != nil {
diff --git a/datasource/mongo/heartbeat/heartbeatchecker/heartbeat_test.go b/datasource/mongo/heartbeat/heartbeatchecker/heartbeat_test.go
index 5ef1bc9..f77cd8e 100644
--- a/datasource/mongo/heartbeat/heartbeatchecker/heartbeat_test.go
+++ b/datasource/mongo/heartbeat/heartbeatchecker/heartbeat_test.go
@@ -19,12 +19,12 @@ package heartbeatchecker
 
 import (
 	"context"
-	"fmt"
 	"testing"
 	"time"
 
 	"github.com/apache/servicecomb-service-center/datasource/mongo"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
+	"github.com/apache/servicecomb-service-center/pkg/log"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/go-chassis/v2/storage"
 	"github.com/stretchr/testify/assert"
@@ -41,7 +41,7 @@ func init() {
 func TestUpdateInstanceRefreshTime(t *testing.T) {
 	t.Run("update instance refresh time: if the instance does not exist,the update should fail", func(t *testing.T) {
 		err := updateInstanceRefreshTime(context.Background(), "not-exist", "not-exist")
-		fmt.Println(err)
+		log.Error("", err)
 		assert.NotNil(t, err)
 	})
 
@@ -58,8 +58,8 @@ func TestUpdateInstanceRefreshTime(t *testing.T) {
 		err = updateInstanceRefreshTime(context.Background(), instance1.InstanceInfo.ServiceId, instance1.InstanceInfo.InstanceId)
 		assert.Equal(t, nil, err)
 		filter := bson.M{
-			mongo.InstanceID: instance1.InstanceInfo.InstanceId,
-			mongo.ServiceID:  instance1.InstanceInfo.ServiceId,
+			mongo.StringBuilder([]string{mongo.ColumnInstanceInfo, mongo.ColumnInstanceID}): instance1.InstanceInfo.InstanceId,
+			mongo.StringBuilder([]string{mongo.ColumnInstanceInfo, mongo.ColumnServiceID}):  instance1.InstanceInfo.ServiceId,
 		}
 		result, err := client.GetMongoClient().FindOne(context.Background(), mongo.CollectionInstance, filter)
 		assert.Nil(t, err)
@@ -68,7 +68,7 @@ func TestUpdateInstanceRefreshTime(t *testing.T) {
 		assert.Nil(t, err)
 		assert.NotEqual(t, instance1.RefreshTime, ins.RefreshTime)
 		filter = bson.M{
-			mongo.InstanceID: instance1.InstanceInfo.InstanceId,
+			mongo.StringBuilder([]string{mongo.ColumnInstanceInfo, mongo.ColumnInstanceID}): instance1.InstanceInfo.InstanceId,
 		}
 		_, err = client.GetMongoClient().Delete(context.Background(), mongo.CollectionInstance, filter)
 		assert.Nil(t, err)
diff --git a/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker.go b/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker.go
index 822ed82..fad3ec0 100644
--- a/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker.go
+++ b/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker.go
@@ -24,6 +24,8 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	pb "github.com/go-chassis/cari/discovery"
+
+	"fmt"
 )
 
 func init() {
@@ -41,8 +43,7 @@ func (h *HeartBeatChecker) Heartbeat(ctx context.Context, request *pb.HeartbeatR
 	remoteIP := util.GetIPFromContext(ctx)
 	err := updateInstanceRefreshTime(ctx, request.ServiceId, request.InstanceId)
 	if err != nil {
-		log.Errorf(err, "heartbeat failed, instance[%s]. operator %s",
-			request.InstanceId, remoteIP)
+		log.Error(fmt.Sprintf("heartbeat failed, instance[%s]. operator %s", request.InstanceId, remoteIP), err)
 		resp := &pb.HeartbeatResponse{
 			Response: pb.CreateResponseWithSCErr(pb.NewError(pb.ErrInstanceNotExists, err.Error())),
 		}
diff --git a/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker_test.go b/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker_test.go
index a519240..ffe82b5 100644
--- a/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker_test.go
+++ b/datasource/mongo/heartbeat/heartbeatchecker/heartbeatchecker_test.go
@@ -58,7 +58,7 @@ func TestHeartbeat(t *testing.T) {
 		assert.Nil(t, err)
 		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
 		filter := bson.M{
-			mongo.InstanceID: instance1.InstanceInfo.InstanceId,
+			mongo.StringBuilder([]string{mongo.ColumnInstanceInfo, mongo.ColumnInstanceID}): instance1.InstanceInfo.InstanceId,
 		}
 		_, err = client.GetMongoClient().Delete(context.Background(), mongo.CollectionInstance, filter)
 		assert.Nil(t, err)
diff --git a/datasource/mongo/heartbeat/manager.go b/datasource/mongo/heartbeat/manager.go
index 4a1e46f..279e72a 100644
--- a/datasource/mongo/heartbeat/manager.go
+++ b/datasource/mongo/heartbeat/manager.go
@@ -48,11 +48,11 @@ func Init(opts Options) error {
 
 func New(opts Options) (HealthCheck, error) {
 	if opts.PluginImplName == "" {
-		return nil, fmt.Errorf("plugin implement name is nil")
+		return nil, ErrPluginNameNil
 	}
 	f, ok := plugins[opts.PluginImplName]
 	if !ok {
-		return nil, fmt.Errorf("plugin implement not supported [#{opts.PluginImplName}]")
+		return nil, ErrPluginNotSupport
 	}
 	return f(opts)
 }
diff --git a/datasource/mongo/mongo.go b/datasource/mongo/mongo.go
index 7d93769..6e96711 100644
--- a/datasource/mongo/mongo.go
+++ b/datasource/mongo/mongo.go
@@ -39,7 +39,7 @@ type DataSource struct {
 
 func NewDataSource(opts datasource.Options) (datasource.DataSource, error) {
 	// TODO: construct a reasonable DataSource instance
-	log.Warnf("dependency data source enable etcd mode")
+	log.Warn("dependency data source enable etcd mode")
 
 	inst := &DataSource{
 		SchemaEditable: opts.SchemaEditable,
@@ -71,7 +71,7 @@ func (ds *DataSource) initPlugins() error {
 	kind := config.GetString("registry.heartbeat.kind", "heartbeatchecker", config.WithStandby("heartbeat_plugin"))
 	err := heartbeat.Init(heartbeat.Options{PluginImplName: heartbeat.ImplName(kind)})
 	if err != nil {
-		log.Fatalf(err, "heartbeat init failed")
+		log.Fatal("heartbeat init failed", err)
 		return err
 	}
 	return nil
diff --git a/datasource/mongo/ms.go b/datasource/mongo/ms.go
index f1befa3..63204aa 100644
--- a/datasource/mongo/ms.go
+++ b/datasource/mongo/ms.go
@@ -19,7 +19,6 @@ package mongo
 
 import (
 	"context"
-	"errors"
 	"fmt"
 	"strconv"
 	"time"
@@ -27,6 +26,7 @@ import (
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/heartbeat"
+	"github.com/apache/servicecomb-service-center/pkg/gopool"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	apt "github.com/apache/servicecomb-service-center/server/core"
@@ -86,7 +86,8 @@ func (ds *DataSource) RegisterService(ctx context.Context, request *pb.CreateSer
 	}
 
 	remoteIP := util.GetIPFromContext(ctx)
-	log.Infof("create micro-service[%s][%s] successfully,operator: %s", service.ServiceId, insertRes.InsertedID, remoteIP)
+	log.Info(fmt.Sprintf("create micro-service[%s][%s] successfully,operator: %s",
+		service.ServiceId, insertRes.InsertedID, remoteIP))
 
 	return &pb.CreateServiceResponse{
 		Response:  pb.CreateResponse(pb.ResponseSuccess, "Register service successfully"),
@@ -100,7 +101,7 @@ func (ds *DataSource) GetServices(ctx context.Context, request *pb.GetServicesRe
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
 
-	filter := bson.M{Domain: domain, Project: project}
+	filter := bson.M{ColumnDomain: domain, ColumnProject: project}
 
 	services, err := GetServices(ctx, filter)
 	if err != nil {
@@ -119,7 +120,10 @@ func (ds *DataSource) GetApplications(ctx context.Context, request *pb.GetAppsRe
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
 
-	filter := bson.M{Domain: domain, Project: project, ServiceEnv: request.Environment}
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnEnv}): request.Environment}
 
 	services, err := GetServices(ctx, filter)
 	if err != nil {
@@ -155,7 +159,7 @@ func (ds *DataSource) GetService(ctx context.Context, request *pb.GetServiceRequ
 	*pb.GetServiceResponse, error) {
 	svc, err := GetService(ctx, GeneratorServiceFilter(ctx, request.ServiceId))
 	if err != nil {
-		log.Errorf(err, "failed to get single service [%s] from mongo", request.ServiceId)
+		log.Error(fmt.Sprintf("failed to get single service %s from mongo", request.ServiceId), err)
 		return &pb.GetServiceResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, "get service data from mongodb failed."),
 		}, err
@@ -281,24 +285,23 @@ func DelServicePri(ctx context.Context, serviceID string, force bool) (*pb.Respo
 	}
 
 	if serviceID == apt.Service.ServiceId {
-		err := errors.New("not allow to delete service center")
-		log.Errorf(err, "%s micro-service[%s] failed, operator: %s", title, serviceID, remoteIP)
-		return pb.CreateResponse(pb.ErrInvalidParams, err.Error()), nil
+		log.Error(fmt.Sprintf("%s micro-service %s failed, operator: %s", title, serviceID, remoteIP), ErrNotAllowDeleteSC)
+		return pb.CreateResponse(pb.ErrInvalidParams, ErrNotAllowDeleteSC.Error()), nil
 	}
 	microservice, err := GetService(ctx, GeneratorServiceFilter(ctx, serviceID))
 	if err != nil {
-		log.Errorf(err, "%s micro-service[%s] failed, get service file failed, operator: %s",
-			title, serviceID, remoteIP)
+		log.Error(fmt.Sprintf("%s micro-service %s failed, get service file failed, operator: %s",
+			title, serviceID, remoteIP), err)
 		return pb.CreateResponse(pb.ErrInternal, err.Error()), err
 	}
 	if microservice == nil {
-		log.Errorf(err, "%s micro-service[%s] failed, service does not exist, operator: %s",
-			title, serviceID, remoteIP)
+		log.Error(fmt.Sprintf("%s micro-service %s failed, service does not exist, operator: %s",
+			title, serviceID, remoteIP), err)
 		return pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."), nil
 	}
 	// 强制删除,则与该服务相关的信息删除,非强制删除: 如果作为该被依赖(作为provider,提供服务,且不是只存在自依赖)或者存在实例,则不能删除
 	if !force {
-		log.Infof("force delete,should del instance...")
+		log.Info("force delete,should del instance...")
 		//todo wait for dep interface
 	}
 	filter := GeneratorServiceFilter(ctx, serviceID)
@@ -329,9 +332,13 @@ func (ds *DataSource) UpdateService(ctx context.Context, request *pb.UpdateServi
 		}, nil
 	}
 
-	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), bson.M{"$set": bson.M{ServiceModTime: strconv.FormatInt(time.Now().Unix(), 10), ServiceProperty: request.Properties}})
+	updateData := bson.M{
+		"$set": bson.M{
+			StringBuilder([]string{ColumnServiceInfo, ColumnModTime}):  strconv.FormatInt(time.Now().Unix(), 10),
+			StringBuilder([]string{ColumnServiceInfo, ColumnProperty}): request.Properties}}
+	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), updateData)
 	if err != nil {
-		log.Errorf(err, "update service [%s] properties failed, update mongo failed", request.ServiceId)
+		log.Error(fmt.Sprintf("update service %s properties failed, update mongo failed", request.ServiceId), err)
 		return &pb.UpdateServicePropsResponse{
 			Response: pb.CreateResponse(pb.ErrUnavailableBackend, "Update doc in mongo failed."),
 		}, nil
@@ -362,8 +369,7 @@ func (ds *DataSource) GetServiceDetail(ctx context.Context, request *pb.GetServi
 	svc := mgSvc.ServiceInfo
 	versions, err := GetServicesVersions(ctx, bson.M{})
 	if err != nil {
-		log.Errorf(err, "get service[%s/%s/%s] all versions failed",
-			svc.Environment, svc.AppId, svc.ServiceName)
+		log.Error(fmt.Sprintf("get service %s %s %s all versions failed", svc.Environment, svc.AppId, svc.ServiceName), err)
 		return &pb.GetServiceDetailResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, err
@@ -403,7 +409,7 @@ func (ds *DataSource) GetServicesInfo(ctx context.Context, request *pb.GetServic
 	//todo add get statistics info
 	services, err := GetMongoServices(ctx, bson.M{})
 	if err != nil {
-		log.Errorf(err, "get all services by domain failed")
+		log.Error("get all services by domain failed", err)
 		return &pb.GetServicesInfoResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, err
@@ -443,7 +449,7 @@ func (ds *DataSource) GetServicesInfo(ctx context.Context, request *pb.GetServic
 func (ds *DataSource) AddTags(ctx context.Context, request *pb.AddServiceTagsRequest) (*pb.AddServiceTagsResponse, error) {
 	service, err := GetService(ctx, GeneratorServiceFilter(ctx, request.ServiceId))
 	if err != nil {
-		log.Errorf(err, "failed to add tags for service [%s] for get service failed,", request.ServiceId)
+		log.Error(fmt.Sprintf("failed to add tags for service %s for get service failed", request.ServiceId), err)
 		return &pb.AddServiceTagsResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, "Failed to check service exist"),
 		}, nil
@@ -460,9 +466,9 @@ func (ds *DataSource) AddTags(ctx context.Context, request *pb.AddServiceTagsReq
 		}
 		tags[key] = value
 	}
-	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), bson.M{"$set": bson.M{ServiceTag: tags}})
+	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), bson.M{"$set": bson.M{ColumnTag: tags}})
 	if err != nil {
-		log.Errorf(err, "update service [%s] tags failed.", request.ServiceId)
+		log.Error(fmt.Sprintf("update service %s tags failed.", request.ServiceId), err)
 		return &pb.AddServiceTagsResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, nil
@@ -475,7 +481,7 @@ func (ds *DataSource) AddTags(ctx context.Context, request *pb.AddServiceTagsReq
 func (ds *DataSource) GetTags(ctx context.Context, request *pb.GetServiceTagsRequest) (*pb.GetServiceTagsResponse, error) {
 	svc, err := GetService(ctx, GeneratorServiceFilter(ctx, request.ServiceId))
 	if err != nil {
-		log.Errorf(err, "failed to get service [%s] tags", request.ServiceId)
+		log.Error(fmt.Sprintf("failed to get service %s tags", request.ServiceId), err)
 		return &pb.GetServiceTagsResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, nil
@@ -494,7 +500,7 @@ func (ds *DataSource) GetTags(ctx context.Context, request *pb.GetServiceTagsReq
 func (ds *DataSource) UpdateTag(ctx context.Context, request *pb.UpdateServiceTagRequest) (*pb.UpdateServiceTagResponse, error) {
 	svc, err := GetService(ctx, GeneratorServiceFilter(ctx, request.ServiceId))
 	if err != nil {
-		log.Errorf(err, "failed to get service [%s] tags", request.ServiceId)
+		log.Error(fmt.Sprintf("failed to get %s tags", request.ServiceId), err)
 		return &pb.UpdateServiceTagResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, nil
@@ -518,9 +524,9 @@ func (ds *DataSource) UpdateTag(ctx context.Context, request *pb.UpdateServiceTa
 	}
 	newTags[request.Key] = request.Value
 
-	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), bson.M{"$set": bson.M{ServiceTag: newTags}})
+	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), bson.M{"$set": bson.M{ColumnTag: newTags}})
 	if err != nil {
-		log.Errorf(err, "update service [%s] tags failed.", request.ServiceId)
+		log.Error(fmt.Sprintf("update service %s tags failed", request.ServiceId), err)
 		return &pb.UpdateServiceTagResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, nil
@@ -533,7 +539,7 @@ func (ds *DataSource) UpdateTag(ctx context.Context, request *pb.UpdateServiceTa
 func (ds *DataSource) DeleteTags(ctx context.Context, request *pb.DeleteServiceTagsRequest) (*pb.DeleteServiceTagsResponse, error) {
 	svc, err := GetService(ctx, GeneratorServiceFilter(ctx, request.ServiceId))
 	if err != nil {
-		log.Errorf(err, "failed to get service [%s] tags", request.ServiceId)
+		log.Error(fmt.Sprintf("failed to get service %s tags", request.ServiceId), err)
 		return &pb.DeleteServiceTagsResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, nil
@@ -558,9 +564,9 @@ func (ds *DataSource) DeleteTags(ctx context.Context, request *pb.DeleteServiceT
 			delete(newTags, key)
 		}
 	}
-	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), bson.M{"$set": bson.M{ServiceTag: newTags}})
+	err = UpdateService(ctx, GeneratorServiceFilter(ctx, request.ServiceId), bson.M{"$set": bson.M{ColumnTag: newTags}})
 	if err != nil {
-		log.Errorf(err, "delete service [%s] tags failed.", request.ServiceId)
+		log.Error(fmt.Sprintf("delete service %s tags failed", request.ServiceId), err)
 		return &pb.DeleteServiceTagsResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
 		}, nil
@@ -698,7 +704,7 @@ func (ds *DataSource) ModifySchema(ctx context.Context, request *pb.ModifySchema
 	defer session.EndSession(ctx)
 	err = ds.modifySchema(ctx, request.ServiceId, &schema)
 	if err != nil {
-		log.Errorf(err, "modify schema[%s/%s] failed, operator: %s", serviceID, schemaID, remoteIP)
+		log.Error(fmt.Sprintf("modify schema %s %s failed, operator %s", serviceID, schemaID, remoteIP), err)
 		errAbort := session.AbortTransaction(ctx)
 		if errAbort != nil {
 			return &pb.ModifySchemaResponse{
@@ -715,7 +721,7 @@ func (ds *DataSource) ModifySchema(ctx context.Context, request *pb.ModifySchema
 			Response: pb.CreateResponse(pb.ErrInternal, "Txn ModifySchema CommitTransaction failed."),
 		}, err
 	}
-	log.Infof("modify schema[%s/%s] successfully, operator: %s", serviceID, schemaID, remoteIP)
+	log.Info(fmt.Sprintf("modify schema[%s/%s] successfully, operator: %s", serviceID, schemaID, remoteIP))
 	return &pb.ModifySchemaResponse{
 		Response: pb.CreateResponse(pb.ResponseSuccess, "modify schema info success."),
 	}, nil
@@ -791,13 +797,13 @@ func (ds *DataSource) modifySchema(ctx context.Context, serviceID string, schema
 		}
 		if schema != nil {
 			if len(schema.Summary) == 0 {
-				log.Errorf(err, "modify schema[%s/%s] failed, get schema summary failed, operator: %s",
-					serviceID, schema.SchemaId, remoteIP)
+				log.Error(fmt.Sprintf("modify schema %s %s failed, get schema summary failed, operator: %s",
+					serviceID, schema.SchemaId, remoteIP), err)
 				return pb.NewError(pb.ErrUnavailableBackend, err.Error())
 			}
 			if len(respSchema.SchemaSummary) != 0 {
-				log.Errorf(err, "%s mode, schema[%s/%s] already exist, can not be changed, operator: %s",
-					pb.ENV_PROD, serviceID, schema.SchemaId, remoteIP)
+				log.Error(fmt.Sprintf("mode, schema %s %s already exist, can not be changed, operator: %s",
+					serviceID, schema.SchemaId, remoteIP), err)
 				return pb.NewError(pb.ErrModifySchemaNotAllow, "schema already exist, can not be changed request "+pb.ENV_PROD)
 			}
 		}
@@ -812,12 +818,14 @@ func (ds *DataSource) modifySchema(ctx context.Context, serviceID string, schema
 		}
 	}
 	if len(newSchemas) != len(microservice.Schemas) {
-		err := UpdateService(ctx, GeneratorServiceFilter(ctx, serviceID), bson.M{"$set": bson.M{ServiceSchemas: newSchemas}})
+
+		updateData := bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnSchemas}): newSchemas}
+		err := UpdateService(ctx, GeneratorServiceFilter(ctx, serviceID), bson.M{"$set": updateData})
 		if err != nil {
 			return pb.NewError(pb.ErrInternal, err.Error())
 		}
 	}
-	newSchema := bson.M{"$set": bson.M{SchemaInfo: schema.Schema, SchemaSummary: schema.Summary}}
+	newSchema := bson.M{"$set": bson.M{ColumnSchemaInfo: schema.Schema, ColumnSchemaSummary: schema.Summary}}
 	err = UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId), newSchema, options.FindOneAndUpdate().SetUpsert(true))
 	if err != nil {
 		return pb.NewError(pb.ErrInternal, err.Error())
@@ -830,8 +838,7 @@ func (ds *DataSource) modifySchemas(ctx context.Context, service *pb.MicroServic
 	serviceID := service.ServiceId
 	schemasFromDatabase, err := GetSchemas(ctx, GeneratorServiceFilter(ctx, serviceID))
 	if err != nil {
-		log.Errorf(nil, "modify service[%s] schemas failed, get schemas failed, operator: %s",
-			serviceID, remoteIP)
+		log.Error(fmt.Sprintf("modify service %s schemas failed, get schemas failed, operator: %s", serviceID, remoteIP), err)
 		return pb.NewError(pb.ErrUnavailableBackend, err.Error())
 	}
 	needUpdateSchemas, needAddSchemas, needDeleteSchemas, nonExistSchemaIds :=
@@ -839,16 +846,17 @@ func (ds *DataSource) modifySchemas(ctx context.Context, service *pb.MicroServic
 	if !ds.isSchemaEditable(service) {
 		if len(service.Schemas) == 0 {
 			//todo add quota check
-			err := UpdateService(ctx, GeneratorServiceFilter(ctx, serviceID), bson.M{"$set": bson.M{ServiceSchemas: nonExistSchemaIds}})
+			updateData := bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnSchemas}): nonExistSchemaIds}
+			err := UpdateService(ctx, GeneratorServiceFilter(ctx, serviceID), bson.M{"$set": updateData})
 			if err != nil {
-				log.Errorf(err, "modify service[%s] schemas failed, update service.Schemas failed, operator: %s",
-					serviceID, remoteIP)
+				log.Error(fmt.Sprintf("modify service %s schemas failed, update service.Schemas failed, operator: %s",
+					serviceID, remoteIP), err)
 				return pb.NewError(pb.ErrInternal, err.Error())
 			}
 		} else {
 			if len(nonExistSchemaIds) != 0 {
 				errInfo := fmt.Errorf("non-existent schemaIDs %v", nonExistSchemaIds)
-				log.Errorf(errInfo, "modify service[%s] schemas failed, operator: %s", serviceID, remoteIP)
+				log.Error(fmt.Sprintf("modify service %s schemas failed, operator: %s", serviceID, remoteIP), err)
 				return pb.NewError(pb.ErrUndefinedSchemaID, errInfo.Error())
 			}
 			for _, needUpdateSchema := range needUpdateSchemas {
@@ -857,20 +865,20 @@ func (ds *DataSource) modifySchemas(ctx context.Context, service *pb.MicroServic
 					return pb.NewError(pb.ErrInternal, err.Error())
 				}
 				if !exist {
-					err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, needUpdateSchema.SchemaId), bson.M{"$set": bson.M{SchemaInfo: needUpdateSchema.Schema, SchemaSummary: needUpdateSchema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
+					err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, needUpdateSchema.SchemaId), bson.M{"$set": bson.M{ColumnSchemaInfo: needUpdateSchema.Schema, ColumnSchemaSummary: needUpdateSchema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
 					if err != nil {
 						return pb.NewError(pb.ErrInternal, err.Error())
 					}
 				} else {
-					log.Warnf("schema[%s/%s] and it's summary already exist, skip to update, operator: %s",
-						serviceID, needUpdateSchema.SchemaId, remoteIP)
+					log.Warn(fmt.Sprintf("schema[%s/%s] and it's summary already exist, skip to update, operator: %s",
+						serviceID, needUpdateSchema.SchemaId, remoteIP))
 				}
 			}
 		}
 
 		for _, schema := range needAddSchemas {
-			log.Infof("add new schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP)
-			err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId), bson.M{"$set": bson.M{SchemaInfo: schema.Schema, SchemaSummary: schema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
+			log.Info(fmt.Sprintf("add new schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP))
+			err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId), bson.M{"$set": bson.M{ColumnSchemaInfo: schema.Schema, ColumnSchemaSummary: schema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
 			if err != nil {
 				return pb.NewError(pb.ErrInternal, err.Error())
 			}
@@ -879,8 +887,8 @@ func (ds *DataSource) modifySchemas(ctx context.Context, service *pb.MicroServic
 
 		var schemaIDs []string
 		for _, schema := range needAddSchemas {
-			log.Infof("add new schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP)
-			err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId), bson.M{"$set": bson.M{SchemaInfo: schema.Schema, SchemaSummary: schema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
+			log.Info(fmt.Sprintf("add new schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP))
+			err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId), bson.M{"$set": bson.M{ColumnSchemaInfo: schema.Schema, ColumnSchemaSummary: schema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
 			if err != nil {
 				return pb.NewError(pb.ErrInternal, err.Error())
 			}
@@ -888,8 +896,8 @@ func (ds *DataSource) modifySchemas(ctx context.Context, service *pb.MicroServic
 		}
 
 		for _, schema := range needUpdateSchemas {
-			log.Infof("update schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP)
-			err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId), bson.M{"$set": bson.M{SchemaInfo: schema.Schema, SchemaSummary: schema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
+			log.Info(fmt.Sprintf("update schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP))
+			err := UpdateSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId), bson.M{"$set": bson.M{ColumnSchemaInfo: schema.Schema, ColumnSchemaSummary: schema.Summary}}, options.FindOneAndUpdate().SetUpsert(true))
 			if err != nil {
 				return pb.NewError(pb.ErrInternal, err.Error())
 			}
@@ -897,17 +905,17 @@ func (ds *DataSource) modifySchemas(ctx context.Context, service *pb.MicroServic
 		}
 
 		for _, schema := range needDeleteSchemas {
-			log.Infof("delete non-existent schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP)
+			log.Info(fmt.Sprintf("delete non-existent schema[%s/%s], operator: %s", serviceID, schema.SchemaId, remoteIP))
 			err = DeleteSchema(ctx, GeneratorSchemaFilter(ctx, serviceID, schema.SchemaId))
 			if err != nil {
 				return pb.NewError(pb.ErrInternal, err.Error())
 			}
 		}
 
-		err := UpdateService(ctx, GeneratorServiceFilter(ctx, serviceID), bson.M{"$set": bson.M{ServiceSchemas: schemaIDs}})
+		updateData := bson.M{StringBuilder([]string{ColumnServiceInfo, ColumnSchemas}): schemaIDs}
+		err := UpdateService(ctx, GeneratorServiceFilter(ctx, serviceID), bson.M{"$set": updateData})
 		if err != nil {
-			log.Errorf(err, "modify service[%s] schemas failed, update service.Schemas failed, operator: %s",
-				serviceID, remoteIP)
+			log.Error(fmt.Sprintf("modify service %s schemas failed, update service.Schemas failed, operator: %s", serviceID, remoteIP), err)
 			return pb.NewError(pb.ErrInternal, err.Error())
 		}
 	}
@@ -917,7 +925,7 @@ func (ds *DataSource) modifySchemas(ctx context.Context, service *pb.MicroServic
 func (ds *DataSource) AddRule(ctx context.Context, request *pb.AddServiceRulesRequest) (*pb.AddServiceRulesResponse, error) {
 	exist, err := ServiceExistID(ctx, request.ServiceId)
 	if err != nil {
-		log.Errorf(err, "failed to add rules for service [%s] for get service failed,", request.ServiceId)
+		log.Error(fmt.Sprintf("failed to add rules for service %s for get service failed", request.ServiceId), err)
 		return &pb.AddServiceRulesResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, "Failed to check service exist"),
 		}, nil
@@ -1013,7 +1021,7 @@ func (ds *DataSource) DeleteRule(ctx context.Context, request *pb.DeleteServiceR
 	*pb.DeleteServiceRulesResponse, error) {
 	exist, err := ServiceExistID(ctx, request.ServiceId)
 	if err != nil {
-		log.Errorf(err, "failed to add tags for service [%s] for get service failed,", request.ServiceId)
+		log.Error(fmt.Sprintf("failed to add tags for service %s for get service failed", request.ServiceId), err)
 		return &pb.DeleteServiceRulesResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, "Failed to check service exist"),
 		}, err
@@ -1046,7 +1054,6 @@ func (ds *DataSource) UpdateRule(ctx context.Context, request *pb.UpdateServiceR
 	if err != nil {
 		return &pb.UpdateServiceRuleResponse{
 			Response: pb.CreateResponse(pb.ErrServiceNotExists, "UpdateRule failed for get service failed."),
-			//Schemas:  nil,
 		}, nil
 	}
 	if !exist {
@@ -1077,12 +1084,14 @@ func (ds *DataSource) UpdateRule(ctx context.Context, request *pb.UpdateServiceR
 		}, nil
 	}
 
-	newRule := bson.M{"$set": bson.M{RuleRuletype: request.Rule.RuleType,
-		RulePattern: request.Rule.Pattern, RuleAttribute: request.Rule.Attribute,
-		RuleDescription: request.Rule.Description,
-		RuleModTime:     strconv.FormatInt(time.Now().Unix(), 10)}}
+	newRule := bson.M{
+		StringBuilder([]string{ColumnRuleInfo, ColumnRuleType}):    request.Rule.RuleType,
+		StringBuilder([]string{ColumnRuleInfo, ColumnPattern}):     request.Rule.Pattern,
+		StringBuilder([]string{ColumnRuleInfo, ColumnAttribute}):   request.Rule.Attribute,
+		StringBuilder([]string{ColumnRuleInfo, ColumnDescription}): request.Rule.Description,
+		StringBuilder([]string{ColumnRuleInfo, ColumnModTime}):     strconv.FormatInt(time.Now().Unix(), 10)}
 
-	err = UpdateRule(ctx, GeneratorRuleFilter(ctx, request.ServiceId, request.RuleId), newRule)
+	err = UpdateRule(ctx, GeneratorRuleFilter(ctx, request.ServiceId, request.RuleId), bson.M{"$set": newRule})
 	if err != nil {
 		return &pb.UpdateServiceRuleResponse{
 			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
@@ -1188,7 +1197,7 @@ func getServiceDetailUtil(ctx context.Context, mgs *Service, countOnly bool, opt
 		case "rules":
 			rules, err := GetRules(ctx, mgs.ServiceInfo.ServiceId)
 			if err != nil {
-				log.Errorf(err, "get service[%s]'s all rules failed", mgs.ServiceInfo.ServiceId)
+				log.Error(fmt.Sprintf("get service %s's all rules failed", mgs.ServiceInfo.ServiceId), err)
 				return nil, err
 			}
 			for _, rule := range rules {
@@ -1200,7 +1209,7 @@ func getServiceDetailUtil(ctx context.Context, mgs *Service, countOnly bool, opt
 		case "schemas":
 			schemas, err := GetSchemas(ctx, GeneratorServiceFilter(ctx, mgs.ServiceInfo.ServiceId))
 			if err != nil {
-				log.Errorf(err, "get service[%s]'s all schemas failed", mgs.ServiceInfo.ServiceId)
+				log.Error(fmt.Sprintf("get service %s's all schemas failed", mgs.ServiceInfo.ServiceId), err)
 				return nil, err
 			}
 			serviceDetail.SchemaInfos = schemas
@@ -1209,7 +1218,7 @@ func getServiceDetailUtil(ctx context.Context, mgs *Service, countOnly bool, opt
 		case "":
 			continue
 		default:
-			log.Errorf(nil, "request option[%s] is invalid", opt)
+			log.Info(fmt.Sprintf("request option %s is invalid", opt))
 		}
 	}
 	return serviceDetail, nil
@@ -1222,7 +1231,7 @@ func UpdateService(ctx context.Context, filter interface{}, m bson.M) error {
 func GetRules(ctx context.Context, serviceID string) ([]*pb.ServiceRule, error) {
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
-	filter := bson.M{Domain: domain, Project: project, RuleServiceID: serviceID}
+	filter := bson.M{ColumnDomain: domain, ColumnProject: project, ColumnServiceID: serviceID}
 
 	ruleRes, err := client.GetMongoClient().Find(ctx, CollectionRule, filter)
 	if err != nil {
@@ -1254,7 +1263,7 @@ func DeleteSchema(ctx context.Context, filter interface{}) error {
 		return err
 	}
 	if !res {
-		return errors.New("delete schema failed")
+		return ErrDeleteSchemaFailed
 	}
 	return nil
 }
@@ -1267,39 +1276,61 @@ func GeneratorServiceFilter(ctx context.Context, serviceID string) bson.M {
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
 
-	return bson.M{Domain: domain, Project: project, ServiceServiceID: serviceID}
+	return bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceID}): serviceID}
 }
 
 func GeneratorServiceNameFilter(ctx context.Context, service *pb.MicroServiceKey) bson.M {
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
 
-	return bson.M{Domain: domain, Project: project, ServiceEnv: service.Environment, ServiceAppID: service.AppId, ServiceServiceName: service.ServiceName, ServiceVersion: service.Version}
+	return bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):         service.Environment,
+		StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):       service.AppId,
+		StringBuilder([]string{ColumnServiceInfo, ColumnServiceName}): service.ServiceName,
+		StringBuilder([]string{ColumnServiceInfo, ColumnVersion}):     service.Version}
 }
 
 func GeneratorServiceAliasFilter(ctx context.Context, service *pb.MicroServiceKey) bson.M {
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
 
-	return bson.M{Domain: domain, Project: project, ServiceEnv: service.Environment, ServiceAppID: service.AppId, ServiceAlias: service.Alias, ServiceVersion: service.Version}
+	return bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnServiceInfo, ColumnEnv}):     service.Environment,
+		StringBuilder([]string{ColumnServiceInfo, ColumnAppID}):   service.AppId,
+		StringBuilder([]string{ColumnServiceInfo, ColumnAlias}):   service.Alias,
+		StringBuilder([]string{ColumnServiceInfo, ColumnVersion}): service.Version}
 }
 
 func GeneratorRuleAttFilter(ctx context.Context, serviceID, attribute, pattern string) bson.M {
-	return bson.M{RuleServiceID: serviceID, RuleAttribute: attribute, RulePattern: pattern}
+	return bson.M{
+		ColumnServiceID: serviceID,
+		StringBuilder([]string{ColumnRuleInfo, ColumnAttribute}): attribute,
+		StringBuilder([]string{ColumnRuleInfo, ColumnPattern}):   pattern}
 }
 
 func GeneratorSchemaFilter(ctx context.Context, serviceID, schemaID string) bson.M {
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
 
-	return bson.M{Domain: domain, Project: project, SchemaServiceID: serviceID, SchemaID: schemaID}
+	return bson.M{ColumnDomain: domain, ColumnProject: project, ColumnServiceID: serviceID, ColumnSchemaID: schemaID}
 }
 
 func GeneratorRuleFilter(ctx context.Context, serviceID, ruleID string) bson.M {
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
 
-	return bson.M{Domain: domain, Project: project, RuleServiceID: serviceID, RuleRuleID: ruleID}
+	return bson.M{
+		ColumnDomain:    domain,
+		ColumnProject:   project,
+		ColumnServiceID: serviceID,
+		StringBuilder([]string{ColumnRuleInfo, ColumnRuleID}): ruleID}
 }
 
 func GetSchemas(ctx context.Context, filter bson.M) ([]*pb.Schema, error) {
@@ -1346,56 +1377,876 @@ func SchemaExist(ctx context.Context, serviceID, schemaID string) (bool, error)
 
 // Instance management
 func (ds *DataSource) RegisterInstance(ctx context.Context, request *pb.RegisterInstanceRequest) (*pb.RegisterInstanceResponse, error) {
-	return &pb.RegisterInstanceResponse{}, nil
+	remoteIP := util.GetIPFromContext(ctx)
+	instance := request.Instance
+
+	// 允许自定义 id
+	if len(instance.InstanceId) > 0 {
+		resp, err := ds.Heartbeat(ctx, &pb.HeartbeatRequest{
+			InstanceId: instance.InstanceId,
+			ServiceId:  instance.ServiceId,
+		})
+		if err != nil || resp == nil {
+			log.Error(fmt.Sprintf("register service %s's instance failed, endpoints %s, host '%s', operator %s",
+				instance.ServiceId, instance.Endpoints, instance.HostName, remoteIP), err)
+			return &pb.RegisterInstanceResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, nil
+		}
+		switch resp.Response.GetCode() {
+		case pb.ResponseSuccess:
+			log.Info(fmt.Sprintf("register instance successful, reuse instance[%s/%s], operator %s",
+				instance.ServiceId, instance.InstanceId, remoteIP))
+			return &pb.RegisterInstanceResponse{
+				Response:   resp.Response,
+				InstanceId: instance.InstanceId,
+			}, nil
+		case pb.ErrInstanceNotExists:
+			// register a new one
+			return registryInstance(ctx, request)
+		default:
+			log.Error(fmt.Sprintf("register instance failed, reuse instance %s %s, operator %s",
+				instance.ServiceId, instance.InstanceId, remoteIP), err)
+			return &pb.RegisterInstanceResponse{
+				Response: resp.Response,
+			}, err
+		}
+	}
+
+	if err := preProcessRegisterInstance(ctx, instance); err != nil {
+		log.Error(fmt.Sprintf("register service %s instance failed, endpoints %s, host %s operator %s",
+			instance.ServiceId, instance.Endpoints, instance.HostName, remoteIP), err)
+		return &pb.RegisterInstanceResponse{
+			Response: pb.CreateResponseWithSCErr(err),
+		}, nil
+	}
+	return registryInstance(ctx, request)
 }
 
 // GetInstances returns instances under the current domain
 func (ds *DataSource) GetInstance(ctx context.Context, request *pb.GetOneInstanceRequest) (*pb.GetOneInstanceResponse, error) {
-	return &pb.GetOneInstanceResponse{}, nil
+	service := &Service{}
+	var err error
+	if len(request.ConsumerServiceId) > 0 {
+		filter := GeneratorServiceFilter(ctx, request.ConsumerServiceId)
+		service, err = GetService(ctx, filter)
+		if err != nil {
+			log.Error(fmt.Sprintf(" get consumer failed, consumer %s find provider instance %s",
+				request.ConsumerServiceId, request.ProviderInstanceId), err)
+			return &pb.GetOneInstanceResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, err
+		}
+		if service == nil {
+			log.Error(fmt.Sprintf("consumer does not exist, consumer %s find provider instance %s %s",
+				request.ConsumerServiceId, request.ProviderServiceId, request.ProviderInstanceId), err)
+			return &pb.GetOneInstanceResponse{
+				Response: pb.CreateResponse(pb.ErrServiceNotExists,
+					fmt.Sprintf("Consumer[%s] does not exist.", request.ConsumerServiceId)),
+			}, nil
+		}
+	}
+
+	filter := GeneratorServiceFilter(ctx, request.ProviderServiceId)
+	provider, err := GetService(ctx, filter)
+	if err != nil {
+		log.Error(fmt.Sprintf("get provider failed, consumer %s find provider instance %s %s",
+			request.ConsumerServiceId, request.ProviderServiceId, request.ProviderInstanceId), err)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if provider == nil {
+		log.Error(fmt.Sprintf("provider does not exist, consumer %s find provider instance %s %s",
+			request.ConsumerServiceId, request.ProviderServiceId, request.ProviderInstanceId), err)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists,
+				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
+		}, nil
+	}
+
+	findFlag := func() string {
+		return fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instance[%s]",
+			request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+			provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version,
+			request.ProviderInstanceId)
+	}
+
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter = bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
+	findOneRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	if err != nil {
+		mes := fmt.Errorf("%s failed, provider instance does not exist", findFlag())
+		log.Error("FindInstances.GetWithProviderID failed", err)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrInstanceNotExists, mes.Error()),
+		}, nil
+	}
+	var instance Instance
+	err = findOneRes.Decode(&instance)
+	if err != nil {
+		log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag()), err)
+		return &pb.GetOneInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+
+	return &pb.GetOneInstanceResponse{
+		Response: pb.CreateResponse(pb.ResponseSuccess, "Get instance successfully."),
+		Instance: instance.InstanceInfo,
+	}, nil
 }
 
 func (ds *DataSource) GetInstances(ctx context.Context, request *pb.GetInstancesRequest) (*pb.GetInstancesResponse, error) {
-	return &pb.GetInstancesResponse{}, nil
+	service := &Service{}
+	var err error
+
+	if len(request.ConsumerServiceId) > 0 {
+		filter := GeneratorServiceFilter(ctx, request.ConsumerServiceId)
+		service, err = GetService(ctx, filter)
+		if err != nil {
+			log.Error(fmt.Sprintf("get consumer failed, consumer %s find provider %sinstances",
+				request.ConsumerServiceId, request.ProviderServiceId), err)
+			return &pb.GetInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, err
+		}
+		if service == nil {
+			log.Error(fmt.Sprintf("consumer does not exist, consumer %s find provider %s instances",
+				request.ConsumerServiceId, request.ProviderServiceId), err)
+			return &pb.GetInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrServiceNotExists,
+					fmt.Sprintf("Consumer[%s] does not exist.", request.ConsumerServiceId)),
+			}, nil
+		}
+	}
+
+	filter := GeneratorServiceFilter(ctx, request.ProviderServiceId)
+	provider, err := GetService(ctx, filter)
+	if err != nil {
+		log.Error(fmt.Sprintf("get provider failed, consumer %s find provider instances %s",
+			request.ConsumerServiceId, request.ProviderServiceId), err)
+		return &pb.GetInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if provider == nil {
+		log.Error(fmt.Sprintf("provider does not exist, consumer %s find provider %s  instances",
+			request.ConsumerServiceId, request.ProviderServiceId), err)
+		return &pb.GetInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists,
+				fmt.Sprintf("Provider[%s] does not exist.", request.ProviderServiceId)),
+		}, nil
+	}
+
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s][%s/%s/%s/%s] instances",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.ServiceInfo.ServiceId, provider.ServiceInfo.Environment, provider.ServiceInfo.AppId, provider.ServiceInfo.ServiceName, provider.ServiceInfo.Version)
+
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter = bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	if err != nil {
+		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		return &pb.GetInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if resp == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("FindInstancesCache.Get failed", mes)
+		return &pb.GetInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
+		}, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag), err)
+			return &pb.GetInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+
+	return &pb.GetInstancesResponse{
+		Response:  pb.CreateResponse(pb.ResponseSuccess, "Query service instances successfully."),
+		Instances: instances,
+	}, nil
 }
 
 // GetProviderInstances returns instances under the specified domain
 func (ds *DataSource) GetProviderInstances(ctx context.Context, request *pb.GetProviderInstancesRequest) (instances []*pb.MicroServiceInstance, rev string, err error) {
-	return nil, "", nil
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): request.ProviderServiceId}
+
+	findRes, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	if err != nil {
+		return
+	}
+
+	for findRes.Next(ctx) {
+		var mongoInstance Instance
+		err := findRes.Decode(&mongoInstance)
+		if err == nil {
+			instances = append(instances, mongoInstance.InstanceInfo)
+		}
+	}
+
+	return instances, "", nil
 }
 
 func (ds *DataSource) GetAllInstances(ctx context.Context, request *pb.GetAllInstancesRequest) (*pb.GetAllInstancesResponse, error) {
-	return &pb.GetAllInstancesResponse{}, nil
+
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+
+	filter := bson.M{ColumnDomain: domain, ColumnProject: project}
+
+	findRes, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+	if err != nil {
+		return nil, err
+	}
+	resp := &pb.GetAllInstancesResponse{
+		Response: pb.CreateResponse(pb.ResponseSuccess, "Get all instances successfully"),
+	}
+
+	for findRes.Next(ctx) {
+		var instance Instance
+		err := findRes.Decode(&instance)
+		if err != nil {
+			return &pb.GetAllInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, err
+		}
+		resp.Instances = append(resp.Instances, instance.InstanceInfo)
+	}
+
+	return resp, nil
 }
 
 func (ds *DataSource) BatchGetProviderInstances(ctx context.Context, request *pb.BatchGetInstancesRequest) (instances []*pb.MicroServiceInstance, rev string, err error) {
-	return nil, "", nil
+	if request == nil || len(request.ServiceIds) == 0 {
+		return nil, "", ErrInvalidParamBatchGetInstancesRequest
+	}
+
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+
+	for _, providerServiceID := range request.ServiceIds {
+		filter := bson.M{
+			ColumnDomain:  domain,
+			ColumnProject: project,
+			StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}): providerServiceID}
+		findRes, err := client.GetMongoClient().Find(ctx, CollectionInstance, filter)
+		if err != nil {
+			return instances, "", nil
+		}
+
+		for findRes.Next(ctx) {
+			var mongoInstance Instance
+			err := findRes.Decode(&mongoInstance)
+			if err == nil {
+				instances = append(instances, mongoInstance.InstanceInfo)
+			}
+		}
+	}
+
+	return instances, "", nil
 }
 
 // FindInstances returns instances under the specified domain
 func (ds *DataSource) FindInstances(ctx context.Context, request *pb.FindInstancesRequest) (*pb.FindInstancesResponse, error) {
-	return &pb.FindInstancesResponse{}, nil
+	provider := &pb.MicroServiceKey{
+		Tenant:      util.ParseTargetDomainProject(ctx),
+		Environment: request.Environment,
+		AppId:       request.AppId,
+		ServiceName: request.ServiceName,
+		Alias:       request.ServiceName,
+		Version:     request.VersionRule,
+	}
+
+	return ds.findInstance(ctx, request, provider)
 }
 
 func (ds *DataSource) UpdateInstanceStatus(ctx context.Context, request *pb.UpdateInstanceStatusRequest) (*pb.UpdateInstanceStatusResponse, error) {
-	return &pb.UpdateInstanceStatusResponse{}, nil
+	updateStatusFlag := util.StringJoin([]string{request.ServiceId, request.InstanceId, request.Status}, "/")
+
+	// todo finish get instance
+	instance, err := GetInstance(ctx, request.ServiceId, request.InstanceId)
+	if err != nil {
+		log.Error(fmt.Sprintf("update instance %s status failed", updateStatusFlag), err)
+		return &pb.UpdateInstanceStatusResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if instance == nil {
+		log.Error(fmt.Sprintf("update instance %s status failed, instance does not exist", updateStatusFlag), err)
+		return &pb.UpdateInstanceStatusResponse{
+			Response: pb.CreateResponse(pb.ErrInstanceNotExists, "Service instance does not exist."),
+		}, nil
+	}
+
+	copyInstanceRef := *instance
+	copyInstanceRef.InstanceInfo.Status = request.Status
+
+	if err := UpdateInstanceS(ctx, copyInstanceRef.InstanceInfo); err != nil {
+		log.Error(fmt.Sprintf("update instance %s status failed", updateStatusFlag), err)
+		resp := &pb.UpdateInstanceStatusResponse{
+			Response: pb.CreateResponseWithSCErr(err),
+		}
+		if err.InternalError() {
+			return resp, err
+		}
+		return resp, nil
+	}
+
+	log.Infof("update instance[%s] status successfully", updateStatusFlag)
+	return &pb.UpdateInstanceStatusResponse{
+		Response: pb.CreateResponse(pb.ResponseSuccess, "Update service instance status successfully."),
+	}, nil
 }
 
 func (ds *DataSource) UpdateInstanceProperties(ctx context.Context, request *pb.UpdateInstancePropsRequest) (*pb.UpdateInstancePropsResponse, error) {
-	return &pb.UpdateInstancePropsResponse{}, nil
+	instanceFlag := util.StringJoin([]string{request.ServiceId, request.InstanceId}, "/")
+
+	instance, err := GetInstance(ctx, request.ServiceId, request.InstanceId)
+	if err != nil {
+		log.Error(fmt.Sprintf("update instance %s properties failed", instanceFlag), err)
+		return &pb.UpdateInstancePropsResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if instance == nil {
+		log.Error(fmt.Sprintf("update instance %s properties failed, instance does not exist", instanceFlag), err)
+		return &pb.UpdateInstancePropsResponse{
+			Response: pb.CreateResponse(pb.ErrInstanceNotExists, "Service instance does not exist."),
+		}, nil
+	}
+
+	copyInstanceRef := *instance
+	copyInstanceRef.InstanceInfo.Properties = request.Properties
+
+	// todo finish update instance
+	if err := UpdateInstanceP(ctx, copyInstanceRef.InstanceInfo); err != nil {
+		log.Error(fmt.Sprintf("update instance %s properties failed", instanceFlag), err)
+		resp := &pb.UpdateInstancePropsResponse{
+			Response: pb.CreateResponseWithSCErr(err),
+		}
+		if err.InternalError() {
+			return resp, err
+		}
+		return resp, nil
+	}
+
+	log.Infof("update instance[%s] properties successfully", instanceFlag)
+	return &pb.UpdateInstancePropsResponse{
+		Response: pb.CreateResponse(pb.ResponseSuccess, "Update service instance properties successfully."),
+	}, nil
 }
 
 func (ds *DataSource) UnregisterInstance(ctx context.Context, request *pb.UnregisterInstanceRequest) (*pb.UnregisterInstanceResponse, error) {
-	return &pb.UnregisterInstanceResponse{}, nil
+	remoteIP := util.GetIPFromContext(ctx)
+	serviceID := request.ServiceId
+	instanceID := request.InstanceId
+
+	instanceFlag := util.StringJoin([]string{serviceID, instanceID}, "/")
+
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}):  serviceID,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnInstanceID}): instanceID}
+	_, err := client.GetMongoClient().Delete(ctx, CollectionInstance, filter)
+	if err != nil {
+		log.Error(fmt.Sprintf("unregister instance failed, instance %s, operator %s revoke instance failed", instanceFlag, remoteIP), err)
+		return &pb.UnregisterInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, "delete instance failed"),
+		}, err
+	}
+
+	log.Infof("unregister instance[%s], operator %s", instanceFlag, remoteIP)
+	return &pb.UnregisterInstanceResponse{
+		Response: pb.CreateResponse(pb.ResponseSuccess, "Unregister service instance successfully."),
+	}, nil
 }
 
 func (ds *DataSource) Heartbeat(ctx context.Context, request *pb.HeartbeatRequest) (*pb.HeartbeatResponse, error) {
-	return heartbeat.Instance().Heartbeat(ctx, request)
+	remoteIP := util.GetIPFromContext(ctx)
+	instanceFlag := util.StringJoin([]string{request.ServiceId, request.InstanceId}, "/")
+	err := KeepAliveLease(ctx, request)
+	if err != nil {
+		log.Error(fmt.Sprintf("heartbeat failed, instance %s operator %s", instanceFlag, remoteIP), err)
+		resp := &pb.HeartbeatResponse{
+			Response: pb.CreateResponseWithSCErr(err),
+		}
+		if err.InternalError() {
+			return resp, err
+		}
+		return resp, nil
+	}
+	return &pb.HeartbeatResponse{
+		Response: pb.CreateResponse(pb.ResponseSuccess,
+			"Update service instance heartbeat successfully."),
+	}, nil
 }
 
 func (ds *DataSource) HeartbeatSet(ctx context.Context, request *pb.HeartbeatSetRequest) (*pb.HeartbeatSetResponse, error) {
-	return &pb.HeartbeatSetResponse{}, nil
+	domainProject := util.ParseDomainProject(ctx)
+
+	heartBeatCount := len(request.Instances)
+	existFlag := make(map[string]bool, heartBeatCount)
+	instancesHbRst := make(chan *pb.InstanceHbRst, heartBeatCount)
+	noMultiCounter := 0
+
+	for _, heartbeatElement := range request.Instances {
+		if _, ok := existFlag[heartbeatElement.ServiceId+heartbeatElement.InstanceId]; ok {
+			log.Warnf("instance[%s/%s] is duplicate request heartbeat set",
+				heartbeatElement.ServiceId, heartbeatElement.InstanceId)
+			continue
+		} else {
+			existFlag[heartbeatElement.ServiceId+heartbeatElement.InstanceId] = true
+			noMultiCounter++
+		}
+		gopool.Go(getHeartbeatFunc(ctx, domainProject, instancesHbRst, heartbeatElement))
+	}
+
+	count := 0
+	successFlag := false
+	failFlag := false
+	instanceHbRstArr := make([]*pb.InstanceHbRst, 0, heartBeatCount)
+
+	for hbRst := range instancesHbRst {
+		count++
+		if len(hbRst.ErrMessage) != 0 {
+			failFlag = true
+		} else {
+			successFlag = true
+		}
+		instanceHbRstArr = append(instanceHbRstArr, hbRst)
+		if count == noMultiCounter {
+			close(instancesHbRst)
+		}
+	}
+
+	if !failFlag && successFlag {
+		log.Infof("batch update heartbeats[%d] successfully", count)
+		return &pb.HeartbeatSetResponse{
+			Response:  pb.CreateResponse(pb.ResponseSuccess, "Heartbeat set successfully."),
+			Instances: instanceHbRstArr,
+		}, nil
+	}
+
+	log.Info(fmt.Sprintf("batch update heartbeats failed %v", request.Instances))
+	return &pb.HeartbeatSetResponse{
+		Response:  pb.CreateResponse(pb.ErrInstanceNotExists, "Heartbeat set failed."),
+		Instances: instanceHbRstArr,
+	}, nil
 }
 
 func (ds *DataSource) BatchFind(ctx context.Context, request *pb.BatchFindInstancesRequest) (*pb.BatchFindInstancesResponse, error) {
-	return &pb.BatchFindInstancesResponse{}, nil
+	response := &pb.BatchFindInstancesResponse{
+		Response: pb.CreateResponse(pb.ResponseSuccess, "Batch query service instances successfully."),
+	}
+
+	var err error
+
+	response.Services, err = ds.batchFindServices(ctx, request)
+	if err != nil {
+		return &pb.BatchFindInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+
+	response.Instances, err = ds.batchFindInstances(ctx, request)
+	if err != nil {
+		return &pb.BatchFindInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+
+	return response, nil
+}
+
+func registryInstance(ctx context.Context, request *pb.RegisterInstanceRequest) (*pb.RegisterInstanceResponse, error) {
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	remoteIP := util.GetIPFromContext(ctx)
+	instance := request.Instance
+	instanceID := instance.InstanceId
+	data := &Instance{
+		Domain:       domain,
+		Project:      project,
+		RefreshTime:  time.Now(),
+		InstanceInfo: instance,
+	}
+
+	instanceFlag := fmt.Sprintf("endpoints %v, host '%s', serviceID %s",
+		instance.Endpoints, instance.HostName, instance.ServiceId)
+
+	insertRes, err := client.GetMongoClient().Insert(ctx, CollectionInstance, data)
+	if err != nil {
+		log.Error(fmt.Sprintf("register instance failed %s instanceID %s operator %s", instanceFlag, instanceID, remoteIP), err)
+		return &pb.RegisterInstanceResponse{
+			Response: pb.CreateResponse(pb.ErrUnavailableBackend, err.Error()),
+		}, err
+	}
+
+	log.Infof("register instance %s, instanceID %s, operator %s",
+		instanceFlag, insertRes.InsertedID, remoteIP)
+	return &pb.RegisterInstanceResponse{
+		Response:   pb.CreateResponse(pb.ResponseSuccess, "Register service instance successfully."),
+		InstanceId: instanceID,
+	}, nil
+}
+
+func (ds *DataSource) findInstance(ctx context.Context, request *pb.FindInstancesRequest, provider *pb.MicroServiceKey) (*pb.FindInstancesResponse, error) {
+	var err error
+	domainProject := util.ParseDomainProject(ctx)
+	service := &Service{ServiceInfo: &pb.MicroService{Environment: request.Environment}}
+	if len(request.ConsumerServiceId) > 0 {
+		filter := GeneratorServiceFilter(ctx, request.ConsumerServiceId)
+		service, err = GetService(ctx, filter)
+		if err != nil {
+			log.Error(fmt.Sprintf("get consumer failed, consumer %s find provider %s/%s/%s/%s",
+				request.ConsumerServiceId, request.Environment, request.AppId, request.ServiceName, request.VersionRule), err)
+			return &pb.FindInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, err
+		}
+		if service == nil {
+			log.Error(fmt.Sprintf("consumer does not exist, consumer %s find provider %s/%s/%s/%s",
+				request.ConsumerServiceId, request.Environment, request.AppId, request.ServiceName, request.VersionRule), err)
+			return &pb.FindInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrServiceNotExists,
+					fmt.Sprintf("Consumer[%s] does not exist.", request.ConsumerServiceId)),
+			}, nil
+		}
+		provider.Environment = service.ServiceInfo.Environment
+	}
+
+	// provider is not a shared micro-service,
+	// only allow shared micro-service instances found request different domains.
+	ctx = util.SetTargetDomainProject(ctx, util.ParseDomain(ctx), util.ParseProject(ctx))
+	provider.Tenant = util.ParseTargetDomainProject(ctx)
+
+	findFlag := fmt.Sprintf("Consumer[%s][%s/%s/%s/%s] find provider[%s/%s/%s/%s]",
+		request.ConsumerServiceId, service.ServiceInfo.Environment, service.ServiceInfo.AppId, service.ServiceInfo.ServiceName, service.ServiceInfo.Version,
+		provider.Environment, provider.AppId, provider.ServiceName, provider.Version)
+
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	resp, err := client.GetMongoClient().Find(ctx, CollectionInstance, bson.M{ColumnDomain: domain, ColumnProject: project})
+	if err != nil {
+		log.Error(fmt.Sprintf("FindInstancesCache.Get failed %s failed", findFlag), err)
+		return &pb.FindInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+		}, err
+	}
+	if resp == nil {
+		mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+		log.Error("FindInstancesCache.Get failed", mes)
+		return &pb.FindInstancesResponse{
+			Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
+		}, nil
+	}
+
+	var instances []*pb.MicroServiceInstance
+	for resp.Next(ctx) {
+		var instance Instance
+		err := resp.Decode(&instance)
+		if err != nil {
+			log.Error(fmt.Sprintf("FindInstances.GetWithProviderID failed %s failed", findFlag), err)
+			return &pb.FindInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, err
+		}
+		instances = append(instances, instance.InstanceInfo)
+	}
+
+	// add dependency queue
+	if len(request.ConsumerServiceId) > 0 &&
+		len(instances) > 0 {
+		provider, err = ds.reshapeProviderKey(ctx, provider, instances[0].ServiceId)
+		if err != nil {
+			return nil, err
+		}
+		if provider != nil {
+			err = AddServiceVersionRule(ctx, domainProject, service.ServiceInfo, provider)
+		} else {
+			mes := fmt.Errorf("%s failed, provider does not exist", findFlag)
+			log.Error("AddServiceVersionRule failed", mes)
+			return &pb.FindInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrServiceNotExists, mes.Error()),
+			}, nil
+		}
+		if err != nil {
+			log.Error(fmt.Sprintf("AddServiceVersionRule failed %s failed", findFlag), err)
+			return &pb.FindInstancesResponse{
+				Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
+			}, err
+		}
+	}
+
+	return &pb.FindInstancesResponse{
+		Response:  pb.CreateResponse(pb.ResponseSuccess, "Query service instances successfully."),
+		Instances: instances,
+	}, nil
+}
+
+func (ds *DataSource) reshapeProviderKey(ctx context.Context, provider *pb.MicroServiceKey, providerID string) (
+	*pb.MicroServiceKey, error) {
+	//维护version的规则,service name 可能是别名,所以重新获取
+	filter := GeneratorServiceFilter(ctx, providerID)
+	providerService, err := GetService(ctx, filter)
+	if providerService == nil {
+		return nil, err
+	}
+
+	versionRule := provider.Version
+	provider = pb.MicroServiceToKey(provider.Tenant, providerService.ServiceInfo)
+	provider.Version = versionRule
+	return provider, nil
+}
+
+func AddServiceVersionRule(ctx context.Context, domainProject string, consumer *pb.MicroService, provider *pb.MicroServiceKey) error {
+	return nil
+}
+
+func GetInstance(ctx context.Context, serviceID string, instanceID string) (*Instance, error) {
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}):  serviceID,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnInstanceID}): instanceID}
+	findRes, err := client.GetMongoClient().FindOne(ctx, CollectionInstance, filter)
+	if err != nil {
+		return nil, err
+	}
+	var instance *Instance
+	if findRes.Err() != nil {
+		//not get any service,not db err
+		return nil, nil
+	}
+	err = findRes.Decode(&instance)
+	if err != nil {
+		return nil, err
+	}
+	return instance, nil
+}
+
+func UpdateInstanceS(ctx context.Context, instance *pb.MicroServiceInstance) *pb.Error {
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}):  instance.ServiceId,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnInstanceID}): instance.InstanceId}
+	_, err := client.GetMongoClient().Update(ctx, CollectionInstance, filter, bson.M{"$set": bson.M{"instance.motTimestamp": strconv.FormatInt(time.Now().Unix(), 10), "instance.status": instance.Status}})
+	if err != nil {
+		return pb.NewError(pb.ErrUnavailableBackend, err.Error())
+	}
+	return nil
+}
+
+func UpdateInstanceP(ctx context.Context, instance *pb.MicroServiceInstance) *pb.Error {
+	domain := util.ParseDomain(ctx)
+	project := util.ParseProject(ctx)
+	filter := bson.M{
+		ColumnDomain:  domain,
+		ColumnProject: project,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnServiceID}):  instance.ServiceId,
+		StringBuilder([]string{ColumnInstanceInfo, ColumnInstanceID}): instance.InstanceId}
+	_, err := client.GetMongoClient().Update(ctx, CollectionInstance, filter, bson.M{"$set": bson.M{"instance.motTimestamp": strconv.FormatInt(time.Now().Unix(), 10), "instance.properties": instance.Properties}})
+	if err != nil {
+		return pb.NewError(pb.ErrUnavailableBackend, err.Error())
+	}
+	return nil
+}
+
+func KeepAliveLease(ctx context.Context, request *pb.HeartbeatRequest) *pb.Error {
+	_, err := heartbeat.Instance().Heartbeat(ctx, request)
+	if err != nil {
+		return pb.NewError(pb.ErrInstanceNotExists, err.Error())
+	}
+	return nil
+}
+
+func getHeartbeatFunc(ctx context.Context, domainProject string, instancesHbRst chan<- *pb.InstanceHbRst, element *pb.HeartbeatSetElement) func(context.Context) {
+	return func(_ context.Context) {
+		hbRst := &pb.InstanceHbRst{
+			ServiceId:  element.ServiceId,
+			InstanceId: element.InstanceId,
+			ErrMessage: "",
+		}
+
+		req := &pb.HeartbeatRequest{
+			InstanceId: element.InstanceId,
+			ServiceId:  element.ServiceId,
+		}
+
+		err := KeepAliveLease(ctx, req)
+		if err != nil {
+			hbRst.ErrMessage = err.Error()
+			log.Error(fmt.Sprintf("heartbeat set failed %s %s", element.ServiceId, element.InstanceId), err)
+		}
+		instancesHbRst <- hbRst
+	}
+}
+
+func (ds *DataSource) batchFindServices(ctx context.Context, request *pb.BatchFindInstancesRequest) (
+	*pb.BatchFindResult, error) {
+	if len(request.Services) == 0 {
+		return nil, nil
+	}
+	cloneCtx := util.CloneContext(ctx)
+
+	services := &pb.BatchFindResult{}
+	failedResult := make(map[int32]*pb.FindFailedResult)
+	for index, key := range request.Services {
+		findCtx := util.SetContext(cloneCtx, util.CtxRequestRevision, key.Rev)
+		resp, err := ds.FindInstances(findCtx, &pb.FindInstancesRequest{
+			ConsumerServiceId: request.ConsumerServiceId,
+			AppId:             key.Service.AppId,
+			ServiceName:       key.Service.ServiceName,
+			VersionRule:       key.Service.Version,
+			Environment:       key.Service.Environment,
+		})
+		if err != nil {
+			return nil, err
+		}
+		failed, ok := failedResult[resp.Response.GetCode()]
+		AppendFindResponse(findCtx, int64(index), resp.Response, resp.Instances,
+			&services.Updated, &services.NotModified, &failed)
+		if !ok && failed != nil {
+			failedResult[resp.Response.GetCode()] = failed
+		}
+	}
+	for _, result := range failedResult {
+		services.Failed = append(services.Failed, result)
+	}
+	return services, nil
+}
+
+func (ds *DataSource) batchFindInstances(ctx context.Context, request *pb.BatchFindInstancesRequest) (*pb.BatchFindResult, error) {
+	if len(request.Instances) == 0 {
+		return nil, nil
+	}
+	cloneCtx := util.CloneContext(ctx)
+	// can not find the shared provider instances
+	cloneCtx = util.SetTargetDomainProject(cloneCtx, util.ParseDomain(ctx), util.ParseProject(ctx))
+
+	instances := &pb.BatchFindResult{}
+	failedResult := make(map[int32]*pb.FindFailedResult)
+	for index, key := range request.Instances {
+		getCtx := util.SetContext(cloneCtx, util.CtxRequestRevision, key.Rev)
+		resp, err := ds.GetInstance(getCtx, &pb.GetOneInstanceRequest{
+			ConsumerServiceId:  request.ConsumerServiceId,
+			ProviderServiceId:  key.Instance.ServiceId,
+			ProviderInstanceId: key.Instance.InstanceId,
+		})
+		if err != nil {
+			return nil, err
+		}
+		failed, ok := failedResult[resp.Response.GetCode()]
+		AppendFindResponse(getCtx, int64(index), resp.Response, []*pb.MicroServiceInstance{resp.Instance},
+			&instances.Updated, &instances.NotModified, &failed)
+		if !ok && failed != nil {
+			failedResult[resp.Response.GetCode()] = failed
+		}
+	}
+	for _, result := range failedResult {
+		instances.Failed = append(instances.Failed, result)
+	}
+	return instances, nil
+}
+
+func AppendFindResponse(ctx context.Context, index int64, resp *pb.Response, instances []*pb.MicroServiceInstance,
+	updatedResult *[]*pb.FindResult, notModifiedResult *[]int64, failedResult **pb.FindFailedResult) {
+	if code := resp.GetCode(); code != pb.ResponseSuccess {
+		if *failedResult == nil {
+			*failedResult = &pb.FindFailedResult{
+				Error: pb.NewError(code, resp.GetMessage()),
+			}
+		}
+		(*failedResult).Indexes = append((*failedResult).Indexes, index)
+		return
+	}
+	iv, _ := ctx.Value(util.CtxRequestRevision).(string)
+	ov, _ := ctx.Value(util.CtxResponseRevision).(string)
+	if len(iv) > 0 && iv == ov {
+		*notModifiedResult = append(*notModifiedResult, index)
+		return
+	}
+	*updatedResult = append(*updatedResult, &pb.FindResult{
+		Index:     index,
+		Instances: instances,
+		Rev:       ov,
+	})
+}
+
+func preProcessRegisterInstance(ctx context.Context, instance *pb.MicroServiceInstance) *pb.Error {
+	if len(instance.Status) == 0 {
+		instance.Status = pb.MSI_UP
+	}
+
+	if len(instance.InstanceId) == 0 {
+		instance.InstanceId = uuid.Generator().GetInstanceID(ctx)
+	}
+
+	instance.Timestamp = strconv.FormatInt(time.Now().Unix(), 10)
+	instance.ModTimestamp = instance.Timestamp
+
+	// 这里应该根据租约计时
+	renewalInterval := apt.RegistryDefaultLeaseRenewalinterval
+	retryTimes := apt.RegistryDefaultLeaseRetrytimes
+	if instance.HealthCheck == nil {
+		instance.HealthCheck = &pb.HealthCheck{
+			Mode:     pb.CHECK_BY_HEARTBEAT,
+			Interval: renewalInterval,
+			Times:    retryTimes,
+		}
+	} else {
+		// Health check对象仅用于呈现服务健康检查逻辑,如果CHECK_BY_PLATFORM类型,表明由sidecar代发心跳,实例120s超时
+		switch instance.HealthCheck.Mode {
+		case pb.CHECK_BY_HEARTBEAT:
+			d := instance.HealthCheck.Interval * (instance.HealthCheck.Times + 1)
+			if d <= 0 {
+				return pb.NewError(pb.ErrInvalidParams, "Invalid 'healthCheck' settings in request body.")
+			}
+		case pb.CHECK_BY_PLATFORM:
+			// 默认120s
+			instance.HealthCheck.Interval = renewalInterval
+			instance.HealthCheck.Times = retryTimes
+		}
+	}
+
+	filter := GeneratorServiceFilter(ctx, instance.ServiceId)
+	microservice, err := GetService(ctx, filter)
+	if microservice == nil || err != nil {
+		return pb.NewError(pb.ErrServiceNotExists, "Invalid 'serviceID' in request body.")
+	}
+	instance.Version = microservice.ServiceInfo.Version
+	return nil
 }
diff --git a/datasource/mongo/ms_test.go b/datasource/mongo/ms_test.go
index 8a2fb9c..5e4254f 100644
--- a/datasource/mongo/ms_test.go
+++ b/datasource/mongo/ms_test.go
@@ -24,11 +24,13 @@ import (
 	"time"
 
 	"github.com/apache/servicecomb-service-center/datasource"
+	"github.com/apache/servicecomb-service-center/datasource/mongo"
 	"github.com/apache/servicecomb-service-center/datasource/mongo/client"
 	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	pb "github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/go-chassis/v2/storage"
 	"github.com/stretchr/testify/assert"
+	"go.mongodb.org/mongo-driver/bson"
 )
 
 func init() {
@@ -185,34 +187,6 @@ func TestGetService(t *testing.T) {
 
 }
 
-// need mongodb cluster
-//func TestServiceDelete(t *testing.T) {
-//	t.Run("delete service by mongo, should pass", func(t *testing.T) {
-//		request := &pb.CreateServiceRequest{
-//			Service: &pb.MicroService{
-//				ServiceId:   "ms-service-delete-new-id",
-//				ServiceName: "ms-service-delete",
-//				AppId:       "default",
-//				Version:     "1.0.4",
-//				Level:       "BACK",
-//				Properties:  make(map[string]string),
-//			},
-//		}
-//
-//		resp, err := datasource.Instance().RegisterService(getContext(), request)
-//		assert.NoError(t, err)
-//		assert.Equal(t, resp.Response.GetCode(), pb.ResponseSuccess)
-//
-//		res, err := datasource.Instance().UnregisterService(getContext(), &pb.DeleteServiceRequest{
-//			ServiceId: "ms-service-delete-new-id",
-//			Force:     false,
-//		})
-//		fmt.Println(res.Response.Message)
-//		assert.NoError(t, err)
-//		assert.Equal(t, pb.ResponseSuccess, res.Response.GetCode())
-//	})
-//}
-
 func TestUpdateService(t *testing.T) {
 	t.Run("update service by mongo, should pass", func(t *testing.T) {
 		request := &pb.CreateServiceRequest{
@@ -247,7 +221,7 @@ func TestUpdateService(t *testing.T) {
 
 func TestTagsAdd(t *testing.T) {
 	// create service
-	t.Run("create service", func(t *testing.T) {
+	t.Run("create service, the request is valid, should pass", func(t *testing.T) {
 		svc1 := &pb.MicroService{
 			ServiceId:   "service_tag_id",
 			AppId:       "create_tag_group_ms",
@@ -264,7 +238,7 @@ func TestTagsAdd(t *testing.T) {
 	})
 
 	//
-	t.Run("the request is valid", func(t *testing.T) {
+	t.Run("create service, the request is valid, should pass", func(t *testing.T) {
 		defaultQuota := quota.DefaultTagQuota
 		tags := make(map[string]string, defaultQuota)
 		for i := 0; i < defaultQuota; i++ {
@@ -282,7 +256,7 @@ func TestTagsAdd(t *testing.T) {
 }
 
 func TestTagsGet(t *testing.T) {
-	t.Run("create service and add tags", func(t *testing.T) {
+	t.Run("create service and add tags, the request is valid, should pass", func(t *testing.T) {
 		svc := &pb.MicroService{
 			ServiceId:   "get_tag_group_ms_id",
 			AppId:       "get_tag_group_ms",
@@ -318,7 +292,7 @@ func TestTagsGet(t *testing.T) {
 }
 
 func TestTagUpdate(t *testing.T) {
-	t.Run("add service and add tags", func(t *testing.T) {
+	t.Run("add service and add tags, the request is valid, should pass", func(t *testing.T) {
 		svc := &pb.MicroService{
 			ServiceId:   "update_tag_group_ms_id",
 			AppId:       "update_tag_group_ms",
@@ -344,7 +318,7 @@ func TestTagUpdate(t *testing.T) {
 		assert.Equal(t, pb.ResponseSuccess, respAddTags.Response.GetCode())
 	})
 
-	t.Run("the request is valid", func(t *testing.T) {
+	t.Run("the request is valid, should pass", func(t *testing.T) {
 		resp, err := datasource.Instance().UpdateTag(getContext(), &pb.UpdateServiceTagRequest{
 			ServiceId: "update_tag_group_ms_id",
 			Key:       "a",
@@ -356,7 +330,7 @@ func TestTagUpdate(t *testing.T) {
 }
 
 func TestTagsDelete(t *testing.T) {
-	t.Run("create service and add tags", func(t *testing.T) {
+	t.Run("create service and add tags, the request is valid, should pass", func(t *testing.T) {
 		resp, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
 				ServiceId:   "delete_tag_group_ms_id",
@@ -380,7 +354,7 @@ func TestTagsDelete(t *testing.T) {
 		assert.NoError(t, err)
 		assert.Equal(t, pb.ResponseSuccess, respAddTages.Response.GetCode())
 	})
-	t.Run("the request is valid", func(t *testing.T) {
+	t.Run("the request is valid, should pass", func(t *testing.T) {
 		resp, err := datasource.Instance().DeleteTags(getContext(), &pb.DeleteServiceTagsRequest{
 			ServiceId: "delete_tag_group_ms_id",
 			Keys:      []string{"b"},
@@ -398,7 +372,7 @@ func TestTagsDelete(t *testing.T) {
 }
 
 func TestRuleAdd(t *testing.T) {
-	t.Run("register service and datasource.Instance()", func(t *testing.T) {
+	t.Run("register service, the request is valid, should pass", func(t *testing.T) {
 		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
 				ServiceId:   "create_rule_group_ms_id",
@@ -412,7 +386,7 @@ func TestRuleAdd(t *testing.T) {
 		assert.NoError(t, err)
 		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
 	})
-	t.Run("request is valid", func(t *testing.T) {
+	t.Run("register service, the request is valid, should pass", func(t *testing.T) {
 		respAddRule, err := datasource.Instance().AddRule(getContext(), &pb.AddServiceRulesRequest{
 			ServiceId: "create_rule_group_ms_id",
 			Rules: []*pb.AddOrUpdateServiceRule{
@@ -429,7 +403,7 @@ func TestRuleAdd(t *testing.T) {
 		ruleId := respAddRule.RuleIds[0]
 		assert.NotEqual(t, "", ruleId)
 	})
-	t.Run("request rule is already exist", func(t *testing.T) {
+	t.Run("request rule is already exist, should pass", func(t *testing.T) {
 		respAddRule, err := datasource.Instance().AddRule(getContext(), &pb.AddServiceRulesRequest{
 			ServiceId: "create_rule_group_ms_id",
 			Rules: []*pb.AddOrUpdateServiceRule{
@@ -448,7 +422,7 @@ func TestRuleAdd(t *testing.T) {
 }
 
 func TestRuleGet(t *testing.T) {
-	t.Run("register service and rules", func(t *testing.T) {
+	t.Run("register service and rules, the request is valid, should pass", func(t *testing.T) {
 		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
 				ServiceId:   "get_rule_group_ms_id",
@@ -478,7 +452,7 @@ func TestRuleGet(t *testing.T) {
 		ruleId := respAddRule.RuleIds[0]
 		assert.NotEqual(t, "", ruleId)
 	})
-	t.Run("get when request is valid", func(t *testing.T) {
+	t.Run("get rule,  when request is valid, should pass", func(t *testing.T) {
 		respGetRule, err := datasource.Instance().GetRules(getContext(), &pb.GetServiceRulesRequest{
 			ServiceId: "get_rule_group_ms_id",
 		})
@@ -490,7 +464,7 @@ func TestRuleGet(t *testing.T) {
 
 func TestRuleDelete(t *testing.T) {
 	var ruleId string
-	t.Run("register service and rules", func(t *testing.T) {
+	t.Run("register service and rules, when request is valid, should pass", func(t *testing.T) {
 		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
 				ServiceId:   "delete_rule_group_ms_id",
@@ -519,7 +493,7 @@ func TestRuleDelete(t *testing.T) {
 		assert.Equal(t, pb.ResponseSuccess, respAddRule.Response.GetCode())
 		ruleId = respAddRule.RuleIds[0]
 	})
-	t.Run("delete when request is valid", func(t *testing.T) {
+	t.Run("delete rule, when request is valid, should pass", func(t *testing.T) {
 		resp, err := datasource.Instance().DeleteRule(getContext(), &pb.DeleteServiceRulesRequest{
 			ServiceId: "delete_rule_group_ms_id",
 			RuleIds:   []string{ruleId},
@@ -538,7 +512,7 @@ func TestRuleDelete(t *testing.T) {
 
 func TestRuleUpdate(t *testing.T) {
 	var ruleId string
-	t.Run("create service and rules", func(t *testing.T) {
+	t.Run("create service and rules, when request is valid, should pass", func(t *testing.T) {
 		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
 				ServiceId:   "update_rule_group_ms_id",
@@ -568,7 +542,7 @@ func TestRuleUpdate(t *testing.T) {
 		assert.NotEqual(t, "", respAddRule.RuleIds[0])
 		ruleId = respAddRule.RuleIds[0]
 	})
-	t.Run("update when request is valid", func(t *testing.T) {
+	t.Run("update rule, when request is valid, should pass", func(t *testing.T) {
 		resp, err := datasource.Instance().UpdateRule(getContext(), &pb.UpdateServiceRuleRequest{
 			ServiceId: "update_rule_group_ms_id",
 			RuleId:    ruleId,
@@ -584,70 +558,500 @@ func TestRuleUpdate(t *testing.T) {
 	})
 }
 
-// 需要多集群mongo支持
-//func TestSchema(t *testing.T) {
-//	t.Run("create a schema in production env", func(t *testing.T) {
-//		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
-//			Service: &pb.MicroService{
-//				ServiceId:   "create_schema_prod_service_ms_id1",
-//				AppId:       "create_schema_prod_service_ms",
-//				ServiceName: "create_schema_service_service_ms",
-//				Version:     "1.0.0",
-//				Level:       "FRONT",
-//				Status:      pb.MS_UP,
-//				Environment: pb.ENV_PROD,
-//			},
-//		})
-//		assert.NoError(t, err)
-//		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
-//
-//		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
-//			Service: &pb.MicroService{
-//				ServiceId:   "create_schema_prod_service_ms_id2",
-//				AppId:       "create_schema_prod_service_ms",
-//				ServiceName: "create_schema_service_service_ms",
-//				Version:     "1.0.1",
-//				Level:       "FRONT",
-//				Schemas: []string{
-//					"first_schemaId_service_ms",
-//					"second_schemaId_service_ms",
-//				},
-//				Status:      pb.MS_UP,
-//				Environment: pb.ENV_PROD,
-//			},
-//		})
-//		assert.NoError(t, err)
-//		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
-//
-//		respModifySchema, err := datasource.Instance().ModifySchema(getContext(), &pb.ModifySchemaRequest{
-//			ServiceId: "create_schema_prod_service_ms_id1",
-//			SchemaId:  "first_schemaId_service_ms",
-//			Schema:    "first_schema_service_ms",
-//		})
-//		assert.NoError(t, err)
-//		assert.Equal(t, pb.ResponseSuccess, respModifySchema.Response.GetCode())
-//
-//		respModifySchema, err = datasource.Instance().ModifySchema(getContext(), &pb.ModifySchemaRequest{
-//			ServiceId: "create_schema_prod_service_ms_id1",
-//			SchemaId:  "first_schemaId_service_ms",
-//			Schema:    "first_schema_change_service_ms",
-//			Summary:   "first0summary1change_service_ms",
-//		})
-//		assert.NoError(t, err)
-//		assert.Equal(t, pb.ResponseSuccess, respModifySchema.Response.GetCode())
-//		existRes, err := datasource.Instance().ExistSchema(getContext(), &pb.GetExistenceRequest{
-//			ServiceId: "create_schema_prod_service_ms_id1",
-//			SchemaId:  "first_schemaId_service_ms",
-//		})
-//		assert.NoError(t, err)
-//		assert.Equal(t, pb.ResponseSuccess, existRes.Response.GetCode())
-//		assert.Equal(t, "first0summary1change_service_ms", existRes.Summary)
-//
-//		resSchemas, err := datasource.Instance().GetAllSchemas(getContext(), &pb.GetAllSchemaRequest{
-//			ServiceId:  "create_schema_prod_service_ms_id1",
-//			WithSchema: true,
-//		})
-//		assert.NoError(t, err)
-//		assert.Equal(t, 1, len(resSchemas.Schemas))
-//	})
-//}
+func TestInstance_Creat(t *testing.T) {
+	var serviceId string
+
+	t.Run("create service, when request is valid, should pass", func(t *testing.T) {
+		insertRes, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "service1",
+				ServiceName: "create_instance_service_ms",
+				AppId:       "create_instance_ms",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, insertRes.Response.GetCode())
+		serviceId = insertRes.ServiceId
+	})
+
+	t.Run("register instance, when request is valid, should pass", func(t *testing.T) {
+		respCreateInst, err := datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				ServiceId: serviceId,
+				Endpoints: []string{
+					"createInstance_ms:127.0.0.1:8080",
+				},
+				HostName: "UT-HOST",
+				Status:   pb.MSI_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateInst.Response.GetCode())
+		assert.NotEqual(t, "ins_instance", respCreateInst.InstanceId)
+
+		respCreateInst, err = datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				InstanceId: "instance2",
+				ServiceId:  serviceId,
+				Endpoints: []string{
+					"createInstance_ms:127.0.0.1:8080",
+				},
+				HostName: "UT-HOST",
+				Status:   pb.MSI_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateInst.Response.GetCode())
+		assert.Equal(t, "instance2", respCreateInst.InstanceId)
+	})
+
+	t.Run("update the same instance, should pass", func(t *testing.T) {
+		resp, err := datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				ServiceId:  serviceId,
+				InstanceId: "instance3",
+				Endpoints: []string{
+					"sameInstance:127.0.0.1:8080",
+				},
+				HostName: "UT-HOST",
+				Status:   pb.MSI_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+
+		resp, err = datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				ServiceId:  serviceId,
+				InstanceId: "instance4",
+				Endpoints: []string{
+					"sameInstance:127.0.0.1:8080",
+				},
+				HostName: "UT-HOST",
+				Status:   pb.MSI_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+		assert.Equal(t, "instance4", resp.InstanceId)
+	})
+
+	t.Run("delete test data", func(t *testing.T) {
+		_, err := client.GetMongoClient().Delete(getContext(), mongo.CollectionService, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+
+		_, err = client.GetMongoClient().Delete(getContext(), mongo.CollectionInstance, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+	})
+}
+
+func TestInstance_update(t *testing.T) {
+
+	var (
+		serviceId  string
+		instanceId string
+	)
+
+	t.Run("register service and instance, when request is valid, should pass", func(t *testing.T) {
+		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "service1",
+				ServiceName: "update_instance_service_ms",
+				AppId:       "update_instance_service_ms",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		serviceId = respCreateService.ServiceId
+
+		respCreateInstance, err := datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				ServiceId:  serviceId,
+				InstanceId: "instance1",
+				Endpoints: []string{
+					"updateInstance:127.0.0.1:8080",
+				},
+				HostName:   "UT-HOST-MS",
+				Status:     pb.MSI_UP,
+				Properties: map[string]string{"nodeIP": "test"},
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateInstance.Response.GetCode())
+		instanceId = respCreateInstance.InstanceId
+	})
+
+	t.Run("update instance status, should pass", func(t *testing.T) {
+		respUpdateStatus, err := datasource.Instance().UpdateInstanceStatus(getContext(), &pb.UpdateInstanceStatusRequest{
+			ServiceId:  serviceId,
+			InstanceId: instanceId,
+			Status:     pb.MSI_DOWN,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateStatus.Response.GetCode())
+
+		respUpdateStatus, err = datasource.Instance().UpdateInstanceStatus(getContext(), &pb.UpdateInstanceStatusRequest{
+			ServiceId:  serviceId,
+			InstanceId: instanceId,
+			Status:     pb.MSI_OUTOFSERVICE,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateStatus.Response.GetCode())
+
+		respUpdateStatus, err = datasource.Instance().UpdateInstanceStatus(getContext(), &pb.UpdateInstanceStatusRequest{
+			ServiceId:  serviceId,
+			InstanceId: instanceId,
+			Status:     pb.MSI_STARTING,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateStatus.Response.GetCode())
+
+		respUpdateStatus, err = datasource.Instance().UpdateInstanceStatus(getContext(), &pb.UpdateInstanceStatusRequest{
+			ServiceId:  serviceId,
+			InstanceId: instanceId,
+			Status:     pb.MSI_TESTING,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateStatus.Response.GetCode())
+
+		respUpdateStatus, err = datasource.Instance().UpdateInstanceStatus(getContext(), &pb.UpdateInstanceStatusRequest{
+			ServiceId:  serviceId,
+			InstanceId: instanceId,
+			Status:     pb.MSI_UP,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateStatus.Response.GetCode())
+
+		respUpdateStatus, err = datasource.Instance().UpdateInstanceStatus(getContext(), &pb.UpdateInstanceStatusRequest{
+			ServiceId:  serviceId,
+			InstanceId: "notexistins",
+			Status:     pb.MSI_STARTING,
+		})
+		assert.NoError(t, err)
+		assert.NotEqual(t, pb.ResponseSuccess, respUpdateStatus.Response.GetCode())
+	})
+
+	t.Run("update instance properties, should pass", func(t *testing.T) {
+		respUpdateProperties, err := datasource.Instance().UpdateInstanceProperties(getContext(),
+			&pb.UpdateInstancePropsRequest{
+				ServiceId:  serviceId,
+				InstanceId: instanceId,
+				Properties: map[string]string{
+					"test": "test",
+				},
+			})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateProperties.Response.GetCode())
+
+		size := 1000
+		properties := make(map[string]string, size)
+		for i := 0; i < size; i++ {
+			s := strconv.Itoa(i) + strings.Repeat("x", 253)
+			properties[s] = s
+		}
+		respUpdateProperties, err = datasource.Instance().UpdateInstanceProperties(getContext(),
+			&pb.UpdateInstancePropsRequest{
+				ServiceId:  serviceId,
+				InstanceId: instanceId,
+				Properties: properties,
+			})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateProperties.Response.GetCode())
+
+		respUpdateProperties, err = datasource.Instance().UpdateInstanceProperties(getContext(),
+			&pb.UpdateInstancePropsRequest{
+				ServiceId:  serviceId,
+				InstanceId: "not_exist_ins",
+				Properties: map[string]string{
+					"test": "test",
+				},
+			})
+		assert.NoError(t, err)
+		assert.NotEqual(t, pb.ResponseSuccess, respUpdateProperties.Response.GetCode())
+
+		respUpdateProperties, err = datasource.Instance().UpdateInstanceProperties(getContext(),
+			&pb.UpdateInstancePropsRequest{
+				ServiceId:  serviceId,
+				InstanceId: instanceId,
+			})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respUpdateProperties.Response.GetCode())
+
+		respUpdateProperties, err = datasource.Instance().UpdateInstanceProperties(getContext(),
+			&pb.UpdateInstancePropsRequest{
+				ServiceId:  "not_exist_service",
+				InstanceId: instanceId,
+				Properties: map[string]string{
+					"test": "test",
+				},
+			})
+		assert.NoError(t, err)
+		assert.NotEqual(t, pb.ResponseSuccess, respUpdateProperties.Response.GetCode())
+	})
+
+	t.Run("delete test data", func(t *testing.T) {
+		_, err := client.GetMongoClient().Delete(getContext(), mongo.CollectionService, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+
+		_, err = client.GetMongoClient().Delete(getContext(), mongo.CollectionInstance, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+	})
+}
+
+func TestInstance_Query(t *testing.T) {
+
+	var (
+		serviceId1  string
+		instanceId1 string
+	)
+
+	t.Run("register services and instance for testInstance_query, when request is invalid, should pass", func(t *testing.T) {
+		insertServiceRes, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "service1",
+				AppId:       "query_instance_ms",
+				ServiceName: "query_instance_service_ms",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, insertServiceRes.Response.GetCode())
+		serviceId1 = insertServiceRes.ServiceId
+
+		insertInstanceRes, err := datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				InstanceId: "instance1",
+				ServiceId:  serviceId1,
+				HostName:   "UT-HOST-MS",
+				Endpoints: []string{
+					"find:127.0.0.1:8080",
+				},
+				Status: pb.MSI_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, insertInstanceRes.Response.GetCode())
+		instanceId1 = insertInstanceRes.InstanceId
+	})
+
+	t.Run("query instance, when request is invalid, should pass", func(t *testing.T) {
+		findRes, err := datasource.Instance().FindInstances(getContext(), &pb.FindInstancesRequest{
+			ConsumerServiceId: serviceId1,
+			AppId:             "query_instance_ms",
+			ServiceName:       "query_instance_service_ms",
+			VersionRule:       "latest",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, findRes.Response.GetCode())
+		assert.Equal(t, instanceId1, findRes.Instances[0].InstanceId)
+	})
+
+	t.Run("batch query instance, when request is invalid, should pass", func(t *testing.T) {
+		respFind, err := datasource.Instance().BatchFind(getContext(), &pb.BatchFindInstancesRequest{
+			ConsumerServiceId: serviceId1,
+			Services: []*pb.FindService{
+				{
+					Service: &pb.MicroServiceKey{
+						AppId:       "query_instance_ms",
+						ServiceName: "query_instance_service_ms",
+						Version:     "latest",
+					},
+				},
+				{
+					Service: &pb.MicroServiceKey{
+						AppId:       "query_instance_ms",
+						ServiceName: "query_instance_service_ms",
+						Version:     "1.0.0+",
+					},
+				},
+				{
+					Service: &pb.MicroServiceKey{
+						AppId:       "query_instance_ms",
+						ServiceName: "query_instance_service_ms",
+						Version:     "0.0.0",
+					},
+				},
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respFind.Response.GetCode())
+		assert.Equal(t, int64(0), respFind.Services.Updated[0].Index)
+
+	})
+
+	t.Run("delete test data", func(t *testing.T) {
+		_, err := client.GetMongoClient().Delete(getContext(), mongo.CollectionService, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+
+		_, err = client.GetMongoClient().Delete(getContext(), mongo.CollectionInstance, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+	})
+}
+
+func TestInstance_GetOne(t *testing.T) {
+
+	var (
+		serviceId1  string
+		serviceId2  string
+		serviceId3  string
+		instanceId2 string
+	)
+
+	t.Run("register service and instances, when request is invalid, should pass", func(t *testing.T) {
+		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "service1",
+				AppId:       "get_instance_ms",
+				ServiceName: "get_instance_service_ms",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		serviceId1 = respCreateService.ServiceId
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "service2",
+				AppId:       "get_instance_ms",
+				ServiceName: "get_instance_service_ms",
+				Version:     "1.0.5",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		serviceId2 = respCreateService.ServiceId
+
+		respCreateInstance, err := datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				InstanceId: "instance1",
+				ServiceId:  serviceId2,
+				HostName:   "UT-HOST-MS",
+				Endpoints: []string{
+					"get:127.0.0.2:8080",
+				},
+				Status: pb.MSI_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		instanceId2 = respCreateInstance.InstanceId
+
+		respCreateService, err = datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "service3",
+				AppId:       "get_instance_cross_ms",
+				ServiceName: "get_instance_service_ms",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		serviceId3 = respCreateService.ServiceId
+	})
+
+	t.Run("get between diff apps, when request is invalid, should pass", func(t *testing.T) {
+		resp, err := datasource.Instance().GetInstance(getContext(), &pb.GetOneInstanceRequest{
+			ConsumerServiceId:  serviceId3,
+			ProviderServiceId:  serviceId2,
+			ProviderInstanceId: instanceId2,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+	})
+
+	t.Run("get instances, when request is invalid, should pass", func(t *testing.T) {
+		resp, err := datasource.Instance().GetInstances(getContext(), &pb.GetInstancesRequest{
+			ConsumerServiceId: "not-exist-service-ms",
+			ProviderServiceId: serviceId2,
+		})
+		assert.NoError(t, err)
+		assert.NotEqual(t, pb.ResponseSuccess, resp.Response.GetCode())
+		resp, err = datasource.Instance().GetInstances(getContext(), &pb.GetInstancesRequest{
+			ConsumerServiceId: serviceId1,
+			ProviderServiceId: serviceId2,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+	})
+
+	t.Run("delete test data", func(t *testing.T) {
+		_, err := client.GetMongoClient().Delete(getContext(), mongo.CollectionService, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+
+		_, err = client.GetMongoClient().Delete(getContext(), mongo.CollectionInstance, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+	})
+}
+
+func TestInstance_Unregister(t *testing.T) {
+	var (
+		serviceId  string
+		instanceId string
+	)
+
+	t.Run("register service and instances, when request is invalid, should pass", func(t *testing.T) {
+		respCreateService, err := datasource.Instance().RegisterService(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceId:   "service1",
+				AppId:       "unregister_instance_ms",
+				ServiceName: "unregister_instance_service_ms",
+				Version:     "1.0.5",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+			},
+			Tags: map[string]string{
+				"test": "test",
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		serviceId = respCreateService.ServiceId
+
+		respCreateInstance, err := datasource.Instance().RegisterInstance(getContext(), &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				InstanceId: "instance1",
+				ServiceId:  serviceId,
+				HostName:   "UT-HOST-MS",
+				Endpoints: []string{
+					"unregister:127.0.0.2:8080",
+				},
+				Status: pb.MSI_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateInstance.Response.GetCode())
+		instanceId = respCreateInstance.InstanceId
+	})
+
+	t.Run("unregister instance, when request is invalid, should pass", func(t *testing.T) {
+		resp, err := datasource.Instance().UnregisterInstance(getContext(), &pb.UnregisterInstanceRequest{
+			ServiceId:  serviceId,
+			InstanceId: instanceId,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+	})
+
+	t.Run("delete test data", func(t *testing.T) {
+		_, err := client.GetMongoClient().Delete(getContext(), mongo.CollectionService, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+
+		_, err = client.GetMongoClient().Delete(getContext(), mongo.CollectionInstance, bson.M{"domain": "default", "project": "default"})
+		assert.NoError(t, err)
+	})
+}
diff --git a/datasource/mongo/engine.go b/datasource/mongo/util.go
similarity index 60%
copy from datasource/mongo/engine.go
copy to datasource/mongo/util.go
index 246ce78..8de33ae 100644
--- a/datasource/mongo/engine.go
+++ b/datasource/mongo/util.go
@@ -17,29 +17,16 @@
 
 package mongo
 
-import (
-	"context"
-	"time"
+import "strings"
 
-	"github.com/apache/servicecomb-service-center/pkg/cluster"
-)
-
-func (ds *DataSource) SelfRegister(ctx context.Context) error {
-	return nil
-}
-func (ds *DataSource) SelfUnregister(ctx context.Context) error {
-	return nil
-}
-
-// OPS
-func (ds *DataSource) ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error {
-	return nil
-}
-
-func (ds *DataSource) UpgradeVersion(ctx context.Context) error {
-	return nil
-}
-
-func (ds *DataSource) GetClusters(ctx context.Context) (cluster.Clusters, error) {
-	return nil, nil
+func StringBuilder(data []string) string {
+	var str strings.Builder
+	for index, value := range data {
+		if index == 0 {
+			str.WriteString(value)
+		} else {
+			str.WriteString("." + value)
+		}
+	}
+	return str.String()
 }