You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2022/01/13 02:30:31 UTC

[servicecomb-service-center] branch master updated: Feature: add put instance service (#1218)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 3d3acab  Feature: add put instance service (#1218)
3d3acab is described below

commit 3d3acabb40fac8f6845d2c7d403af10bf1df8f79
Author: little-cui <su...@qq.com>
AuthorDate: Thu Jan 13 09:40:46 2022 +0800

    Feature: add put instance service (#1218)
---
 datasource/cache/ms_cache.go                   | 15 +++++
 datasource/etcd/ms.go                          | 29 +++++++++-
 datasource/etcd/util/instance_util.go          |  2 +-
 datasource/instance_test.go                    | 74 ++++++++++++++++---------
 datasource/mongo/client/dao/instance.go        | 17 ------
 datasource/mongo/instance_util.go              |  9 ---
 datasource/mongo/ms.go                         | 47 ++++++++++++----
 datasource/mongo/util/db.go                    |  9 ++-
 datasource/ms.go                               |  1 +
 server/service/disco/instance.go               | 11 ++++
 server/service/disco/instance_test.go          | 76 +++++++++++++++++---------
 server/service/validator/instance_validator.go |  8 +--
 server/service/validator/rbac_validator.go     | 29 +++++++++-
 server/service/validator/validator.go          | 26 ---------
 14 files changed, 229 insertions(+), 124 deletions(-)

diff --git a/datasource/cache/ms_cache.go b/datasource/cache/ms_cache.go
index 41a2bce..b136175 100644
--- a/datasource/cache/ms_cache.go
+++ b/datasource/cache/ms_cache.go
@@ -57,6 +57,9 @@ func genDepServiceKey(ruleType string, service *discovery.MicroService) string {
 }
 
 func GetMicroServiceInstancesByID(ctx context.Context, serviceID string) ([]*discovery.MicroServiceInstance, bool) {
+	if util.NoCache(ctx) {
+		return nil, false
+	}
 	index := genServiceIDIndex(ctx, serviceID)
 	cacheInstances := sd.Store().Instance().Cache().GetValue(index)
 	insts, ok := transCacheToMicroInsts(cacheInstances)
@@ -109,6 +112,9 @@ func GetServiceID(ctx context.Context, key *discovery.MicroServiceKey) (serviceI
 }
 
 func GetServiceByIDAcrossDomain(ctx context.Context, serviceID string) (*model.Service, bool) {
+	if util.NoCache(ctx) {
+		return nil, false
+	}
 	index := genServiceIDIndexAcrossDomain(ctx, serviceID)
 	cacheRes := sd.Store().Service().Cache().GetValue(index)
 
@@ -182,6 +188,9 @@ func genServiceNameIndex(ctx context.Context, key *discovery.MicroServiceKey) st
 }
 
 func CountInstances(ctx context.Context, serviceID string) (int, bool) {
+	if util.NoCache(ctx) {
+		return 0, false
+	}
 	index := genServiceIDIndex(ctx, serviceID)
 	cacheInstances := sd.Store().Instance().Cache().GetValue(index)
 	if len(cacheInstances) == 0 {
@@ -191,6 +200,9 @@ func CountInstances(ctx context.Context, serviceID string) (int, bool) {
 }
 
 func GetInstance(ctx context.Context, serviceID string, instanceID string) (*model.Instance, bool) {
+	if util.NoCache(ctx) {
+		return nil, false
+	}
 	index := generateInstanceIDIndex(util.ParseDomainProject(ctx), serviceID, instanceID)
 	cacheInstance := sd.Store().Instance().Cache().GetValue(index)
 	insts, ok := transCacheToInsts(cacheInstance)
@@ -201,6 +213,9 @@ func GetInstance(ctx context.Context, serviceID string, instanceID string) (*mod
 }
 
 func GetInstances(ctx context.Context) ([]*model.Instance, bool) {
+	if util.NoCache(ctx) {
+		return nil, false
+	}
 	index := util.ParseDomainProject(ctx)
 	cacheInstance := sd.Store().Instance().Cache().GetValue(index)
 	insts, ok := transCacheToInsts(cacheInstance)
diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index f6e685e..18d0095 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -599,7 +599,7 @@ func (ds *MetadataManager) sendHeartbeatInstead(ctx context.Context, instance *p
 
 func (ds *MetadataManager) ExistInstance(ctx context.Context, request *pb.MicroServiceInstanceKey) (*pb.GetExistenceByIDResponse, error) {
 	domainProject := util.ParseDomainProject(ctx)
-	exist, err := eutil.InstanceExist(ctx, domainProject, request.ServiceId, request.InstanceId)
+	exist, err := eutil.ExistInstance(ctx, domainProject, request.ServiceId, request.InstanceId)
 	if err != nil {
 		return nil, pb.NewError(pb.ErrInternal, err.Error())
 	}
@@ -883,6 +883,31 @@ func (ds *MetadataManager) reshapeProviderKey(ctx context.Context, provider *pb.
 	return provider, nil
 }
 
+func (ds *MetadataManager) PutInstance(ctx context.Context, request *pb.RegisterInstanceRequest) error {
+	domainProject := util.ParseDomainProject(ctx)
+	instance := request.Instance
+	serviceID := instance.ServiceId
+	instanceID := instance.InstanceId
+	exist, err := eutil.ExistInstance(ctx, domainProject, serviceID, instanceID)
+	if err != nil {
+		log.Error(fmt.Sprintf("update instance[%s/%s] failed", serviceID, instanceID), err)
+		return pb.NewError(pb.ErrInternal, err.Error())
+	}
+	if !exist {
+		log.Error(fmt.Sprintf("update instance[%s/%s] failed, instance does not exist",
+			serviceID, instanceID), nil)
+		return pb.NewError(pb.ErrInstanceNotExists, "Service instance does not exist.")
+	}
+
+	if err := eutil.UpdateInstance(ctx, domainProject, instance); err != nil {
+		log.Error(fmt.Sprintf("update instance[%s/%s] failed", serviceID, instanceID), err)
+		return err
+	}
+	sendEvent(ctx, sync.UpdateAction, datasource.ResourceInstance, instance)
+	log.Info(fmt.Sprintf("update instance[%s/%s] successfully", serviceID, instanceID))
+	return nil
+}
+
 func (ds *MetadataManager) PutInstanceStatus(ctx context.Context, request *pb.UpdateInstanceStatusRequest) error {
 	domainProject := util.ParseDomainProject(ctx)
 	updateStatusFlag := util.StringJoin([]string{request.ServiceId, request.InstanceId, request.Status}, path.SPLIT)
@@ -899,6 +924,7 @@ func (ds *MetadataManager) PutInstanceStatus(ctx context.Context, request *pb.Up
 
 	copyInstanceRef := *instance
 	copyInstanceRef.Status = request.Status
+	copyInstanceRef.ModTimestamp = strconv.FormatInt(time.Now().Unix(), 10)
 
 	if err := eutil.UpdateInstance(ctx, domainProject, &copyInstanceRef); err != nil {
 		log.Error(fmt.Sprintf("update instance[%s] status failed", updateStatusFlag), err)
@@ -925,6 +951,7 @@ func (ds *MetadataManager) PutInstanceProperties(ctx context.Context, request *p
 
 	copyInstanceRef := *instance
 	copyInstanceRef.Properties = request.Properties
+	copyInstanceRef.ModTimestamp = strconv.FormatInt(time.Now().Unix(), 10)
 
 	if err := eutil.UpdateInstance(ctx, domainProject, &copyInstanceRef); err != nil {
 		log.Error(fmt.Sprintf("update instance[%s] properties failed", instanceFlag), err)
diff --git a/datasource/etcd/util/instance_util.go b/datasource/etcd/util/instance_util.go
index be3071d..a12562d 100644
--- a/datasource/etcd/util/instance_util.go
+++ b/datasource/etcd/util/instance_util.go
@@ -65,7 +65,7 @@ func GetInstance(ctx context.Context, domainProject string, serviceID string, in
 	return resp.Kvs[0].Value.(*pb.MicroServiceInstance), nil
 }
 
-func InstanceExist(ctx context.Context, domainProject string, serviceID string, instanceID string) (bool, error) {
+func ExistInstance(ctx context.Context, domainProject string, serviceID string, instanceID string) (bool, error) {
 	key := path.GenerateInstanceKey(domainProject, serviceID, instanceID)
 	opts := append(FromContext(ctx), etcdadpt.WithStrKey(key))
 	resp, err := sd.Instance().Search(ctx, opts...)
diff --git a/datasource/instance_test.go b/datasource/instance_test.go
index 905e8cc..c24e1b3 100644
--- a/datasource/instance_test.go
+++ b/datasource/instance_test.go
@@ -208,35 +208,33 @@ func TestInstance_Update(t *testing.T) {
 	ctx := getContext()
 	defer datasource.GetMetadataManager().UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceID, Force: true})
 
-	t.Run("register service and instance, should pass", func(t *testing.T) {
-		log.Info("register service")
-		respCreateService, err := datasource.GetMetadataManager().RegisterService(ctx, &pb.CreateServiceRequest{
-			Service: &pb.MicroService{
-				ServiceName: "update_instance_service_ms",
-				AppId:       "update_instance_service_ms",
-				Version:     "1.0.0",
-				Level:       "FRONT",
-				Status:      pb.MS_UP,
-			},
-		})
-		assert.NoError(t, err)
-		serviceID = respCreateService.ServiceId
+	respCreateService, err := datasource.GetMetadataManager().RegisterService(ctx, &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			ServiceName: "update_instance_service_ms",
+			AppId:       "update_instance_service_ms",
+			Version:     "1.0.0",
+			Level:       "FRONT",
+			Status:      pb.MS_UP,
+		},
+	})
+	assert.NoError(t, err)
+	serviceID = respCreateService.ServiceId
 
-		log.Info("create instance")
-		respCreateInstance, err := datasource.GetMetadataManager().RegisterInstance(ctx, &pb.RegisterInstanceRequest{
-			Instance: &pb.MicroServiceInstance{
-				ServiceId: serviceID,
-				Endpoints: []string{
-					"updateInstance:127.0.0.1:8080",
-				},
-				HostName:   "UT-HOST-MS",
-				Status:     pb.MSI_UP,
-				Properties: map[string]string{"nodeIP": "test"},
+	registerInstanceRequest := &pb.RegisterInstanceRequest{
+		Instance: &pb.MicroServiceInstance{
+			ServiceId: serviceID,
+			Endpoints: []string{
+				"updateInstance:127.0.0.1:8080",
 			},
-		})
-		assert.NoError(t, err)
-		instanceID = respCreateInstance.InstanceId
-	})
+			HostName:   "UT-HOST-MS",
+			Status:     pb.MSI_UP,
+			Properties: map[string]string{"nodeIP": "test"},
+		},
+	}
+
+	respCreateInstance, err := datasource.GetMetadataManager().RegisterInstance(ctx, registerInstanceRequest)
+	assert.NoError(t, err)
+	instanceID = respCreateInstance.InstanceId
 
 	t.Run("update instance status", func(t *testing.T) {
 		log.Info("update instance status to DOWN")
@@ -351,6 +349,28 @@ func TestInstance_Update(t *testing.T) {
 		assert.Error(t, testErr)
 		assert.Equal(t, pb.ErrInstanceNotExists, testErr.Code)
 	})
+
+	t.Run("update instance with valid request, should be ok", func(t *testing.T) {
+		registerInstanceRequest.Instance.HostName = "updated"
+		err := datasource.GetMetadataManager().PutInstance(ctx, registerInstanceRequest)
+		assert.NoError(t, err)
+
+		resp, err := datasource.GetMetadataManager().GetInstance(ctx, &pb.GetOneInstanceRequest{
+			ProviderServiceId: serviceID, ProviderInstanceId: instanceID,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, "updated", resp.Instance.HostName)
+	})
+
+	t.Run("update instance with invalid request, should be failed", func(t *testing.T) {
+		err := datasource.GetMetadataManager().PutInstance(ctx, &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{
+				ServiceId:  "not-exit-ms",
+				InstanceId: "not-exist-inst",
+			},
+		})
+		assert.True(t, errsvc.IsErrEqualCode(err, pb.ErrInstanceNotExists))
+	})
 }
 
 func TestInstance_Query(t *testing.T) {
diff --git a/datasource/mongo/client/dao/instance.go b/datasource/mongo/client/dao/instance.go
index daacd6d..395a4a8 100644
--- a/datasource/mongo/client/dao/instance.go
+++ b/datasource/mongo/client/dao/instance.go
@@ -30,23 +30,6 @@ import (
 	mutil "github.com/apache/servicecomb-service-center/datasource/mongo/util"
 )
 
-func GetInstance(ctx context.Context, filter interface{}) (*model.Instance, error) {
-	findRes, err := client.GetMongoClient().FindOne(ctx, model.CollectionInstance, filter)
-	if err != nil {
-		return nil, err
-	}
-	var instance *model.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 GetInstances(ctx context.Context, filter interface{}) ([]*model.Instance, error) {
 	res, err := client.GetMongoClient().Find(ctx, model.CollectionInstance, filter)
 	if err != nil {
diff --git a/datasource/mongo/instance_util.go b/datasource/mongo/instance_util.go
index 90b51a3..0cda6c4 100644
--- a/datasource/mongo/instance_util.go
+++ b/datasource/mongo/instance_util.go
@@ -37,15 +37,6 @@ func ExistInstance(ctx context.Context, serviceID string, instanceID string) (bo
 	return dao.ExistInstance(ctx, serviceID, instanceID)
 }
 
-func GetInstance(ctx context.Context, serviceID string, instanceID string) (*model.Instance, error) {
-	inst, ok := cache.GetInstance(ctx, serviceID, instanceID)
-	if ok && inst != nil {
-		return inst, nil
-	}
-	filter := mutil.NewBasicFilter(ctx, mutil.InstanceServiceID(serviceID), mutil.InstanceInstanceID(instanceID))
-	return dao.GetInstance(ctx, filter)
-}
-
 func GetInstances(ctx context.Context) ([]*model.Instance, error) {
 	insts, ok := cache.GetInstances(ctx)
 	if ok {
diff --git a/datasource/mongo/ms.go b/datasource/mongo/ms.go
index 5b3da9b..45fb2a7 100644
--- a/datasource/mongo/ms.go
+++ b/datasource/mongo/ms.go
@@ -1312,26 +1312,53 @@ func (ds *MetadataManager) FindInstances(ctx context.Context, request *discovery
 	return ds.findInstance(ctx, request, provider, rev)
 }
 
+func (ds *MetadataManager) PutInstance(ctx context.Context, request *discovery.RegisterInstanceRequest) error {
+	instance := request.Instance
+	serviceID := instance.ServiceId
+	instanceID := instance.InstanceId
+	filter := mutil.NewBasicFilter(ctx, mutil.InstanceServiceID(serviceID), mutil.InstanceInstanceID(instanceID))
+	exist, err := ExistInstance(ctx, serviceID, instanceID)
+	if err != nil {
+		log.Error(fmt.Sprintf("update instance %s/%s failed", serviceID, instanceID), err)
+		return discovery.NewError(discovery.ErrInternal, err.Error())
+	}
+	if !exist {
+		log.Error(fmt.Sprintf("update instance %s/%s failed, instance does not exist",
+			serviceID, instanceID), err)
+		return discovery.NewError(discovery.ErrInstanceNotExists, "Service instance does not exist.")
+	}
+
+	setFilter := mutil.NewFilter(
+		mutil.Instance(instance),
+	)
+	updateFilter := mutil.NewFilter(mutil.Set(setFilter))
+	if err := dao.UpdateInstance(ctx, filter, updateFilter); err != nil {
+		log.Error(fmt.Sprintf("update instance %s/%s failed", serviceID, instanceID), err)
+		return err
+	}
+
+	log.Info(fmt.Sprintf("update instance[%s/%s] successfully", serviceID, instanceID))
+	return nil
+}
+
 func (ds *MetadataManager) PutInstanceStatus(ctx context.Context, request *discovery.UpdateInstanceStatusRequest) error {
 	updateStatusFlag := util.StringJoin([]string{request.ServiceId, request.InstanceId, request.Status}, "/")
 
 	// todo finish get instance
 	filter := mutil.NewBasicFilter(ctx, mutil.InstanceServiceID(request.ServiceId), mutil.InstanceInstanceID(request.InstanceId))
-	instance, err := GetInstance(ctx, request.ServiceId, request.InstanceId)
+	exist, err := ExistInstance(ctx, request.ServiceId, request.InstanceId)
 	if err != nil {
 		log.Error(fmt.Sprintf("update instance %s status failed", updateStatusFlag), err)
 		return discovery.NewError(discovery.ErrInternal, err.Error())
 	}
-	if instance == nil {
+	if !exist {
 		log.Error(fmt.Sprintf("update instance %s status failed, instance does not exist", updateStatusFlag), err)
 		return discovery.NewError(discovery.ErrInstanceNotExists, "Service instance does not exist.")
 	}
 
-	copyInstanceRef := *instance
-	copyInstanceRef.Instance.Status = request.Status
 	setFilter := mutil.NewFilter(
 		mutil.InstanceModTime(strconv.FormatInt(time.Now().Unix(), baseTen)),
-		mutil.InstanceStatus(copyInstanceRef.Instance.Status),
+		mutil.InstanceStatus(request.Status),
 	)
 	updateFilter := mutil.NewFilter(mutil.Set(setFilter))
 	if err := dao.UpdateInstance(ctx, filter, updateFilter); err != nil {
@@ -1347,24 +1374,20 @@ func (ds *MetadataManager) PutInstanceProperties(ctx context.Context, request *d
 	instanceFlag := util.StringJoin([]string{request.ServiceId, request.InstanceId}, "/")
 	domain := util.ParseDomain(ctx)
 	project := util.ParseProject(ctx)
-	instance, err := GetInstance(ctx, request.ServiceId, request.InstanceId)
+	exist, err := ExistInstance(ctx, request.ServiceId, request.InstanceId)
 	if err != nil {
 		log.Error(fmt.Sprintf("update instance %s properties failed", instanceFlag), err)
 		return discovery.NewError(discovery.ErrInternal, err.Error())
 	}
-	if instance == nil {
+	if !exist {
 		log.Error(fmt.Sprintf("update instance %s properties failed, instance does not exist", instanceFlag), err)
 		return discovery.NewError(discovery.ErrInstanceNotExists, "Service instance does not exist.")
 	}
 
-	copyInstanceRef := *instance
-	copyInstanceRef.Instance.Properties = request.Properties
-
-	// todo finish update instance
 	filter := mutil.NewDomainProjectFilter(domain, project, mutil.InstanceServiceID(request.ServiceId), mutil.InstanceInstanceID(request.InstanceId))
 	setFilter := mutil.NewFilter(
 		mutil.InstanceModTime(strconv.FormatInt(time.Now().Unix(), baseTen)),
-		mutil.InstanceProperties(copyInstanceRef.Instance.Properties),
+		mutil.InstanceProperties(request.Properties),
 	)
 	updateFilter := mutil.NewFilter(mutil.Set(setFilter))
 	if err := dao.UpdateInstance(ctx, filter, updateFilter); err != nil {
diff --git a/datasource/mongo/util/db.go b/datasource/mongo/util/db.go
index f87f4fa..a2d663d 100644
--- a/datasource/mongo/util/db.go
+++ b/datasource/mongo/util/db.go
@@ -20,6 +20,7 @@ package util
 import (
 	"context"
 
+	"github.com/go-chassis/cari/discovery"
 	"github.com/go-chassis/cari/rbac"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
@@ -328,9 +329,15 @@ func Tags(tags map[string]string) Option {
 	}
 }
 
+func Instance(instance *discovery.MicroServiceInstance) Option {
+	return func(filter bson.M) {
+		filter[model.ColumnInstance] = instance
+	}
+}
+
 func InstanceModTime(modTime string) Option {
 	return func(filter bson.M) {
-		filter[ConnectWithDot([]string{model.ColumnService, model.ColumnModTime})] = modTime
+		filter[ConnectWithDot([]string{model.ColumnInstance, model.ColumnModTime})] = modTime
 	}
 }
 
diff --git a/datasource/ms.go b/datasource/ms.go
index 5255260..15a9f55 100644
--- a/datasource/ms.go
+++ b/datasource/ms.go
@@ -65,6 +65,7 @@ type MetadataManager interface {
 	ListInstance(ctx context.Context, request *pb.GetInstancesRequest) (*pb.GetInstancesResponse, error)
 	// FindInstances returns instances under the specified domain
 	FindInstances(ctx context.Context, request *pb.FindInstancesRequest) (*pb.FindInstancesResponse, error)
+	PutInstance(ctx context.Context, request *pb.RegisterInstanceRequest) error
 	PutInstanceStatus(ctx context.Context, request *pb.UpdateInstanceStatusRequest) error
 	PutInstanceProperties(ctx context.Context, request *pb.UpdateInstancePropsRequest) error
 	UnregisterInstance(ctx context.Context, request *pb.UnregisterInstanceRequest) error
diff --git a/server/service/disco/instance.go b/server/service/disco/instance.go
index b2fa07d..e510009 100644
--- a/server/service/disco/instance.go
+++ b/server/service/disco/instance.go
@@ -314,6 +314,17 @@ func AppendFindResponse(ctx context.Context, index int64, resp *pb.Response, ins
 	})
 }
 
+func PutInstance(ctx context.Context, in *pb.RegisterInstanceRequest) error {
+	remoteIP := util.GetIPFromContext(ctx)
+
+	if err := validator.ValidateRegisterInstanceRequest(in); err != nil {
+		log.Error(fmt.Sprintf("update instance failed, invalid parameters, operator %s", remoteIP), err)
+		return pb.NewError(pb.ErrInvalidParams, err.Error())
+	}
+
+	return datasource.GetMetadataManager().PutInstance(ctx, in)
+}
+
 func PutInstanceStatus(ctx context.Context, in *pb.UpdateInstanceStatusRequest) error {
 	remoteIP := util.GetIPFromContext(ctx)
 
diff --git a/server/service/disco/instance_test.go b/server/service/disco/instance_test.go
index 0c22de1..8ad970d 100644
--- a/server/service/disco/instance_test.go
+++ b/server/service/disco/instance_test.go
@@ -1985,33 +1985,33 @@ func TestUpdateInstance(t *testing.T) {
 	ctx := getContext()
 	defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceId, Force: true})
 
-	t.Run("prepare data, should be passed", func(t *testing.T) {
-		respCreate, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
-			Service: &pb.MicroService{
-				ServiceName: "update_instance_service",
-				AppId:       "update_instance_service",
-				Version:     "1.0.0",
-				Level:       "FRONT",
-				Status:      pb.MS_UP,
-			},
-		})
-		assert.NoError(t, err)
-		serviceId = respCreate.ServiceId
+	respCreate, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			ServiceName: "update_instance_service",
+			AppId:       "update_instance_service",
+			Version:     "1.0.0",
+			Level:       "FRONT",
+			Status:      pb.MS_UP,
+		},
+	})
+	assert.NoError(t, err)
+	serviceId = respCreate.ServiceId
 
-		resp, err := discosvc.RegisterInstance(ctx, &pb.RegisterInstanceRequest{
-			Instance: &pb.MicroServiceInstance{
-				ServiceId: serviceId,
-				Endpoints: []string{
-					"updateInstance:127.0.0.1:8080",
-				},
-				HostName:   "UT-HOST",
-				Status:     pb.MSI_UP,
-				Properties: map[string]string{"nodeIP": "test"},
+	registerInstanceRequest := &pb.RegisterInstanceRequest{
+		Instance: &pb.MicroServiceInstance{
+			ServiceId: serviceId,
+			Endpoints: []string{
+				"updateInstance:127.0.0.1:8080",
 			},
-		})
-		assert.NoError(t, err)
-		instanceId = resp.InstanceId
-	})
+			HostName:   "UT-HOST",
+			Status:     pb.MSI_UP,
+			Properties: map[string]string{"nodeIP": "test"},
+		},
+	}
+
+	resp, err := discosvc.RegisterInstance(ctx, registerInstanceRequest)
+	assert.NoError(t, err)
+	instanceId = resp.InstanceId
 
 	t.Run("when update instance status, should be passed", func(t *testing.T) {
 		err := discosvc.PutInstanceStatus(ctx, &pb.UpdateInstanceStatusRequest{
@@ -2192,6 +2192,32 @@ func TestUpdateInstance(t *testing.T) {
 		assert.Error(t, testErr)
 		assert.Equal(t, pb.ErrInstanceNotExists, testErr.Code)
 	})
+
+	t.Run("when update instance with valid request, should be passed", func(t *testing.T) {
+		registerInstanceRequest.Instance.HostName = "updated"
+		err := discosvc.PutInstance(ctx, registerInstanceRequest)
+		assert.NoError(t, err)
+
+		resp, err := discosvc.GetInstance(ctx, &pb.GetOneInstanceRequest{
+			ProviderServiceId: serviceId, ProviderInstanceId: instanceId,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, "updated", resp.Instance.HostName)
+	})
+
+	t.Run("when update instance with invalid request, should be failed", func(t *testing.T) {
+		err = discosvc.PutInstance(ctx, &pb.RegisterInstanceRequest{})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		err = discosvc.PutInstance(ctx, &pb.RegisterInstanceRequest{
+			Instance: &pb.MicroServiceInstance{},
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+	})
 }
 
 func assertInstanceContain(t *testing.T, instances []*pb.MicroServiceInstance, instanceID string) {
diff --git a/server/service/validator/instance_validator.go b/server/service/validator/instance_validator.go
index 2a61764..a131950 100644
--- a/server/service/validator/instance_validator.go
+++ b/server/service/validator/instance_validator.go
@@ -87,16 +87,16 @@ func HeartbeatReqValidator() *validate.Validator {
 	})
 }
 
-func UpdateInstanceReqValidator() *validate.Validator {
+func UpdateInstanceStatusReqValidator() *validate.Validator {
 	return updateInstanceReqValidator.Init(func(v *validate.Validator) {
-		v.AddRules(heartbeatReqValidator.GetRules())
+		v.AddRules(HeartbeatReqValidator().GetRules())
 		v.AddRule("Status", &validate.Rule{Regexp: updateInstStatusRegex})
 	})
 }
 
 func UpdateInstancePropsReqValidator() *validate.Validator {
 	return updateInstancePropsReqValidator.Init(func(v *validate.Validator) {
-		v.AddRules(heartbeatReqValidator.GetRules())
+		v.AddRules(HeartbeatReqValidator().GetRules())
 	})
 }
 
@@ -151,7 +151,7 @@ func ValidateFindManyInstancesRequest(in *discovery.BatchFindInstancesRequest) e
 	return FindManyInstanceReqValidator().Validate(in)
 }
 func ValidateUpdateInstanceStatusRequest(in *discovery.UpdateInstanceStatusRequest) error {
-	return UpdateInstanceReqValidator().Validate(in)
+	return UpdateInstanceStatusReqValidator().Validate(in)
 }
 func ValidateUpdateInstancePropsRequest(in *discovery.UpdateInstancePropsRequest) error {
 	return UpdateInstancePropsReqValidator().Validate(in)
diff --git a/server/service/validator/rbac_validator.go b/server/service/validator/rbac_validator.go
index 5127ab2..136f1b1 100644
--- a/server/service/validator/rbac_validator.go
+++ b/server/service/validator/rbac_validator.go
@@ -19,7 +19,34 @@
 
 package validator
 
-import "github.com/go-chassis/cari/rbac"
+import (
+	"github.com/apache/servicecomb-service-center/pkg/validate"
+	"github.com/go-chassis/cari/rbac"
+)
+
+var createAccountValidator = &validate.Validator{}
+var updateAccountValidator = &validate.Validator{}
+var createRoleValidator = &validate.Validator{}
+
+var changePWDValidator = &validate.Validator{}
+var accountLoginValidator = &validate.Validator{}
+
+func init() {
+	createAccountValidator.AddRule("Name", &validate.Rule{Max: 64, Regexp: nameRegex})
+	createAccountValidator.AddRule("Roles", &validate.Rule{Min: 1, Max: 5, Regexp: nameRegex})
+	createAccountValidator.AddRule("Password", &validate.Rule{Regexp: &validate.PasswordChecker{}})
+	createAccountValidator.AddRule("Status", &validate.Rule{Regexp: accountStatusRegex})
+
+	updateAccountValidator.AddRule("Roles", createAccountValidator.GetRule("Roles"))
+	updateAccountValidator.AddRule("Status", createAccountValidator.GetRule("Status"))
+
+	createRoleValidator.AddRule("Name", &validate.Rule{Max: 64, Regexp: nameRegex})
+
+	changePWDValidator.AddRule("Password", &validate.Rule{Regexp: &validate.PasswordChecker{}})
+	changePWDValidator.AddRule("Name", &validate.Rule{Regexp: nameRegex})
+
+	accountLoginValidator.AddRule("TokenExpirationTime", &validate.Rule{Regexp: &validate.TokenExpirationTimeChecker{}})
+}
 
 func ValidateCreateAccount(a *rbac.Account) error {
 	err := baseCheck(a)
diff --git a/server/service/validator/validator.go b/server/service/validator/validator.go
index e7206e5..684b630 100644
--- a/server/service/validator/validator.go
+++ b/server/service/validator/validator.go
@@ -20,34 +20,8 @@ package validator
 import (
 	"errors"
 	"reflect"
-
-	"github.com/apache/servicecomb-service-center/pkg/validate"
 )
 
-var createAccountValidator = &validate.Validator{}
-var updateAccountValidator = &validate.Validator{}
-var createRoleValidator = &validate.Validator{}
-
-var changePWDValidator = &validate.Validator{}
-var accountLoginValidator = &validate.Validator{}
-
-func init() {
-	createAccountValidator.AddRule("Name", &validate.Rule{Max: 64, Regexp: nameRegex})
-	createAccountValidator.AddRule("Roles", &validate.Rule{Min: 1, Max: 5, Regexp: nameRegex})
-	createAccountValidator.AddRule("Password", &validate.Rule{Regexp: &validate.PasswordChecker{}})
-	createAccountValidator.AddRule("Status", &validate.Rule{Regexp: accountStatusRegex})
-
-	updateAccountValidator.AddRule("Roles", createAccountValidator.GetRule("Roles"))
-	updateAccountValidator.AddRule("Status", createAccountValidator.GetRule("Status"))
-
-	createRoleValidator.AddRule("Name", &validate.Rule{Max: 64, Regexp: nameRegex})
-
-	changePWDValidator.AddRule("Password", &validate.Rule{Regexp: &validate.PasswordChecker{}})
-	changePWDValidator.AddRule("Name", &validate.Rule{Regexp: nameRegex})
-
-	accountLoginValidator.AddRule("TokenExpirationTime", &validate.Rule{Regexp: &validate.TokenExpirationTimeChecker{}})
-}
-
 func baseCheck(v interface{}) error {
 	if v == nil {
 		return errors.New("data is nil")