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 2021/12/14 02:14:08 UTC

[servicecomb-service-center] branch master updated: Refactor schema service (#1169)

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 efb68da  Refactor schema service (#1169)
efb68da is described below

commit efb68da51be6d19f7c29710cffa92b89c26dbbe3
Author: little-cui <su...@qq.com>
AuthorDate: Tue Dec 14 10:14:03 2021 +0800

    Refactor schema service (#1169)
    
    * Refactor schema service
    
    * Add UTs
---
 datasource/etcd/ms.go                              |   89 +-
 datasource/mongo/ms.go                             |   82 +-
 datasource/schema_test.go                          |   76 +-
 pkg/proto/service.go                               |    5 -
 server/plugin/quota/quota.go                       |    2 +-
 .../disco/schema_resource.go}                      |   77 +-
 server/resource/disco/schema_resource_test.go      |  268 +++
 server/resource/register.go                        |    2 +
 server/rest/controller/v3/schema_controller.go     |   14 +-
 server/rest/controller/v4/v4.go                    |    1 -
 server/service/disco/schema.go                     |   41 +-
 server/service/disco/schema_test.go                | 1703 ++++++++++----------
 server/service/disco/service_suite_test.go         |    4 +-
 server/service/govern/view_test.go                 |    2 +-
 14 files changed, 1273 insertions(+), 1093 deletions(-)

diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index b2c5a4f..d0b129f 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -1333,23 +1333,16 @@ func (ds *MetadataManager) ModifySchemas(ctx context.Context, request *pb.Modify
 		if errors.Is(err, datasource.ErrNoData) {
 			log.Debug(fmt.Sprintf("modify service[%s] schemas failed, service does not exist in db, operator: %s",
 				serviceID, remoteIP))
-			return &pb.ModifySchemasResponse{
-				Response: pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."),
-			}, nil
+			return nil, pb.NewError(pb.ErrServiceNotExists, "Service does not exist.")
 		}
 		log.Error(fmt.Sprintf("modify service[%s] schemas failed, get service failed, operator: %s",
 			serviceID, remoteIP), err)
-		return &pb.ModifySchemasResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+		return nil, pb.NewError(pb.ErrInternal, err.Error())
 	}
 
 	if respErr := ds.modifySchemas(ctx, domainProject, serviceInfo, request.Schemas); respErr != nil {
 		log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), respErr)
-		response, err := datasource.WrapErrResponse(respErr)
-		return &pb.ModifySchemasResponse{
-			Response: response,
-		}, err
+		return nil, respErr
 	}
 
 	return &pb.ModifySchemasResponse{
@@ -1371,13 +1364,7 @@ func (ds *MetadataManager) ModifySchema(ctx context.Context, request *pb.ModifyS
 	err := ds.modifySchema(ctx, serviceID, &schema)
 	if err != nil {
 		log.Error(fmt.Sprintf("modify schema[%s/%s] failed, operator: %s", serviceID, schemaID, remoteIP), err)
-		resp := &pb.ModifySchemaResponse{
-			Response: pb.CreateResponseWithSCErr(err),
-		}
-		if err.InternalError() {
-			return resp, err
-		}
-		return resp, nil
+		return nil, err
 	}
 
 	log.Info(fmt.Sprintf("modify schema[%s/%s] successfully, operator: %s", serviceID, schemaID, remoteIP))
@@ -1392,32 +1379,24 @@ func (ds *MetadataManager) ExistSchema(ctx context.Context, request *pb.GetExist
 
 	if !serviceUtil.ServiceExist(ctx, domainProject, request.ServiceId) {
 		log.Warn(fmt.Sprintf("schema[%s/%s] exist failed, service does not exist", request.ServiceId, request.SchemaId))
-		return &pb.GetExistenceResponse{
-			Response: pb.CreateResponse(pb.ErrServiceNotExists, "service does not exist."),
-		}, nil
+		return nil, pb.NewError(pb.ErrServiceNotExists, "service does not exist.")
 	}
 
 	key := path.GenerateServiceSchemaKey(domainProject, request.ServiceId, request.SchemaId)
 	exist, err := checkSchemaInfoExist(ctx, key)
 	if err != nil {
 		log.Error(fmt.Sprintf("schema[%s/%s] exist failed, get schema failed", request.ServiceId, request.SchemaId), err)
-		return &pb.GetExistenceResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+		return nil, pb.NewError(pb.ErrInternal, err.Error())
 	}
 	if !exist {
 		log.Info(fmt.Sprintf("schema[%s/%s] exist failed, schema does not exist", request.ServiceId, request.SchemaId))
-		return &pb.GetExistenceResponse{
-			Response: pb.CreateResponse(pb.ErrSchemaNotExists, "schema does not exist."),
-		}, nil
+		return nil, pb.NewError(pb.ErrSchemaNotExists, "schema does not exist.")
 	}
 	schemaSummary, err := getSchemaSummary(ctx, domainProject, request.ServiceId, request.SchemaId)
 	if err != nil {
 		log.Error(fmt.Sprintf("schema[%s/%s] exist failed, get schema summary failed",
 			request.ServiceId, request.SchemaId), err)
-		return &pb.GetExistenceResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+		return nil, pb.NewError(pb.ErrInternal, err.Error())
 	}
 	return &pb.GetExistenceResponse{
 		Response: pb.CreateResponse(pb.ResponseSuccess, "Schema exist."),
@@ -1432,9 +1411,7 @@ func (ds *MetadataManager) GetSchema(ctx context.Context, request *pb.GetSchemaR
 	if !serviceUtil.ServiceExist(ctx, domainProject, request.ServiceId) {
 		log.Error(fmt.Sprintf("get schema[%s/%s] failed, service does not exist",
 			request.ServiceId, request.SchemaId), nil)
-		return &pb.GetSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."),
-		}, nil
+		return nil, pb.NewError(pb.ErrServiceNotExists, "Service does not exist.")
 	}
 
 	key := path.GenerateServiceSchemaKey(domainProject, request.ServiceId, request.SchemaId)
@@ -1442,25 +1419,19 @@ func (ds *MetadataManager) GetSchema(ctx context.Context, request *pb.GetSchemaR
 	resp, errDo := sd.Schema().Search(ctx, opts...)
 	if errDo != nil {
 		log.Error(fmt.Sprintf("get schema[%s/%s] failed", request.ServiceId, request.SchemaId), errDo)
-		return &pb.GetSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrUnavailableBackend, errDo.Error()),
-		}, errDo
+		return nil, pb.NewError(pb.ErrUnavailableBackend, errDo.Error())
 	}
 	if resp.Count == 0 {
 		log.Error(fmt.Sprintf("get schema[%s/%s] failed, schema does not exists",
 			request.ServiceId, request.SchemaId), errDo)
-		return &pb.GetSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrSchemaNotExists, "Do not have this schema info."),
-		}, nil
+		return nil, pb.NewError(pb.ErrSchemaNotExists, "Do not have this schema info.")
 	}
 
 	schemaSummary, err := getSchemaSummary(ctx, domainProject, request.ServiceId, request.SchemaId)
 	if err != nil {
 		log.Error(fmt.Sprintf("get schema[%s/%s] failed, get schema summary failed",
 			request.ServiceId, request.SchemaId), err)
-		return &pb.GetSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+		return nil, pb.NewError(pb.ErrInternal, err.Error())
 	}
 
 	return &pb.GetSchemaResponse{
@@ -1478,14 +1449,10 @@ func (ds *MetadataManager) GetAllSchemas(ctx context.Context, request *pb.GetAll
 	if err != nil {
 		if errors.Is(err, datasource.ErrNoData) {
 			log.Debug(fmt.Sprintf("get service[%s] all schemas failed, service does not exist in db", request.ServiceId))
-			return &pb.GetAllSchemaResponse{
-				Response: pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."),
-			}, nil
+			return nil, pb.NewError(pb.ErrServiceNotExists, "Service does not exist.")
 		}
 		log.Error(fmt.Sprintf("get service[%s] all schemas failed, get service failed", request.ServiceId), err)
-		return &pb.GetAllSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+		return nil, pb.NewError(pb.ErrInternal, err.Error())
 	}
 
 	schemasList := service.Schemas
@@ -1501,9 +1468,7 @@ func (ds *MetadataManager) GetAllSchemas(ctx context.Context, request *pb.GetAll
 	resp, errDo := sd.SchemaSummary().Search(ctx, opts...)
 	if errDo != nil {
 		log.Error(fmt.Sprintf("get service[%s] all schema summaries failed", request.ServiceId), errDo)
-		return &pb.GetAllSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrUnavailableBackend, errDo.Error()),
-		}, errDo
+		return nil, pb.NewError(pb.ErrUnavailableBackend, errDo.Error())
 	}
 
 	respWithSchema := &kvstore.Response{}
@@ -1513,9 +1478,7 @@ func (ds *MetadataManager) GetAllSchemas(ctx context.Context, request *pb.GetAll
 		respWithSchema, errDo = sd.Schema().Search(ctx, opts...)
 		if errDo != nil {
 			log.Error(fmt.Sprintf("get service[%s] all schemas failed", request.ServiceId), errDo)
-			return &pb.GetAllSchemaResponse{
-				Response: pb.CreateResponse(pb.ErrUnavailableBackend, errDo.Error()),
-			}, errDo
+			return nil, pb.NewError(pb.ErrUnavailableBackend, errDo.Error())
 		}
 	}
 
@@ -1553,9 +1516,7 @@ func (ds *MetadataManager) DeleteSchema(ctx context.Context, request *pb.DeleteS
 	if !serviceUtil.ServiceExist(ctx, domainProject, request.ServiceId) {
 		log.Error(fmt.Sprintf("delete schema[%s/%s] failed, service does not exist, operator: %s",
 			request.ServiceId, request.SchemaId, remoteIP), nil)
-		return &pb.DeleteSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."),
-		}, nil
+		return nil, pb.NewError(pb.ErrServiceNotExists, "Service does not exist.")
 	}
 
 	key := path.GenerateServiceSchemaKey(domainProject, request.ServiceId, request.SchemaId)
@@ -1563,16 +1524,12 @@ func (ds *MetadataManager) DeleteSchema(ctx context.Context, request *pb.DeleteS
 	if err != nil {
 		log.Error(fmt.Sprintf("delete schema[%s/%s] failed, operator: %s",
 			request.ServiceId, request.SchemaId, remoteIP), err)
-		return &pb.DeleteSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrInternal, err.Error()),
-		}, err
+		return nil, pb.NewError(pb.ErrInternal, err.Error())
 	}
 	if !exist {
 		log.Error(fmt.Sprintf("delete schema[%s/%s] failed, schema does not exist, operator: %s",
 			request.ServiceId, request.SchemaId, remoteIP), nil)
-		return &pb.DeleteSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrSchemaNotExists, "Schema info does not exist."),
-		}, nil
+		return nil, pb.NewError(pb.ErrSchemaNotExists, "Schema info does not exist.")
 	}
 	epSummaryKey := path.GenerateServiceSchemaSummaryKey(domainProject, request.ServiceId, request.SchemaId)
 	resp, errDo := etcdadpt.TxnWithCmp(ctx,
@@ -1585,16 +1542,12 @@ func (ds *MetadataManager) DeleteSchema(ctx context.Context, request *pb.DeleteS
 	if errDo != nil {
 		log.Error(fmt.Sprintf("delete schema[%s/%s] failed, operator: %s",
 			request.ServiceId, request.SchemaId, remoteIP), errDo)
-		return &pb.DeleteSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrUnavailableBackend, errDo.Error()),
-		}, errDo
+		return nil, pb.NewError(pb.ErrUnavailableBackend, errDo.Error())
 	}
 	if !resp.Succeeded {
 		log.Error(fmt.Sprintf("delete schema[%s/%s] failed, service does not exist, operator: %s",
 			request.ServiceId, request.SchemaId, remoteIP), nil)
-		return &pb.DeleteSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."),
-		}, nil
+		return nil, pb.NewError(pb.ErrServiceNotExists, "Service does not exist.")
 	}
 
 	log.Info(fmt.Sprintf("delete schema[%s/%s] info successfully, operator: %s",
diff --git a/datasource/mongo/ms.go b/datasource/mongo/ms.go
index 2763de8..d489327 100644
--- a/datasource/mongo/ms.go
+++ b/datasource/mongo/ms.go
@@ -664,26 +664,18 @@ func (ds *MetadataManager) DeleteTags(ctx context.Context, request *discovery.De
 func (ds *MetadataManager) GetSchema(ctx context.Context, request *discovery.GetSchemaRequest) (*discovery.GetSchemaResponse, error) {
 	exist, err := ServiceExistID(ctx, request.ServiceId)
 	if err != nil {
-		return &discovery.GetSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrInternal, "GetSchema failed to check service exist."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrInternal, "GetSchema failed to check service exist.")
 	}
 	if !exist {
-		return &discovery.GetSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrServiceNotExists, "GetSchema service does not exist."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrServiceNotExists, "GetSchema service does not exist.")
 	}
 	filter := mutil.NewBasicFilter(ctx, mutil.ServiceID(request.ServiceId), mutil.SchemaID(request.SchemaId))
 	schema, err := dao.GetSchema(ctx, filter)
 	if err != nil {
-		return &discovery.GetSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrInternal, "GetSchema failed from mongodb."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrInternal, "GetSchema failed from mongodb.")
 	}
 	if schema == nil {
-		return &discovery.GetSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrSchemaNotExists, "Do not have this schema info."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrSchemaNotExists, "Do not have this schema info.")
 	}
 	return &discovery.GetSchemaResponse{
 		Response:      discovery.CreateResponse(discovery.ResponseSuccess, "Get schema info successfully."),
@@ -700,14 +692,10 @@ func (ds *MetadataManager) GetAllSchemas(ctx context.Context, request *discovery
 	if err != nil {
 		if errors.Is(err, datasource.ErrNoData) {
 			log.Debug(fmt.Sprintf("service %s not exist in db", request.ServiceId))
-			return &discovery.GetAllSchemaResponse{
-				Response: discovery.CreateResponse(discovery.ErrServiceNotExists, "GetAllSchemas failed for service not exist"),
-			}, nil
+			return nil, discovery.NewError(discovery.ErrServiceNotExists, "ListSchema failed for service not exist")
 		}
 		log.Error(fmt.Sprintf("get service[%s] all schemas failed, get service failed", request.ServiceId), err)
-		return &discovery.GetAllSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrInternal, err.Error()),
-		}, err
+		return nil, discovery.NewError(discovery.ErrInternal, err.Error())
 	}
 	schemasList := svc.Service.Schemas
 	if len(schemasList) == 0 {
@@ -723,9 +711,7 @@ func (ds *MetadataManager) GetAllSchemas(ctx context.Context, request *discovery
 		filter := mutil.NewDomainProjectFilter(domain, project, mutil.ServiceID(request.ServiceId), mutil.SchemaID(schemaID))
 		schema, err := dao.GetSchema(ctx, filter)
 		if err != nil {
-			return &discovery.GetAllSchemaResponse{
-				Response: discovery.CreateResponse(discovery.ErrInternal, err.Error()),
-			}, err
+			return nil, discovery.NewError(discovery.ErrInternal, err.Error())
 		}
 		if schema == nil {
 			schemas = append(schemas, tempSchema)
@@ -746,26 +732,18 @@ func (ds *MetadataManager) GetAllSchemas(ctx context.Context, request *discovery
 func (ds *MetadataManager) ExistSchema(ctx context.Context, request *discovery.GetExistenceRequest) (*discovery.GetExistenceResponse, error) {
 	exist, err := ServiceExistID(ctx, request.ServiceId)
 	if err != nil {
-		return &discovery.GetExistenceResponse{
-			Response: discovery.CreateResponse(discovery.ErrServiceNotExists, "ExistSchema failed for get service failed"),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrServiceNotExists, "ExistSchema failed for get service failed")
 	}
 	if !exist {
-		return &discovery.GetExistenceResponse{
-			Response: discovery.CreateResponse(discovery.ErrServiceNotExists, "ExistSchema failed for service not exist"),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrServiceNotExists, "ExistSchema failed for service not exist")
 	}
 	filter := mutil.NewBasicFilter(ctx, mutil.ServiceID(request.ServiceId), mutil.SchemaID(request.SchemaId))
 	Schema, err := dao.GetSchema(ctx, filter)
 	if err != nil {
-		return &discovery.GetExistenceResponse{
-			Response: discovery.CreateResponse(discovery.ErrInternal, "ExistSchema failed for get schema failed."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrInternal, "ExistSchema failed for get schema failed.")
 	}
 	if Schema == nil {
-		return &discovery.GetExistenceResponse{
-			Response: discovery.CreateResponse(discovery.ErrSchemaNotExists, "ExistSchema failed for schema not exist."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrSchemaNotExists, "ExistSchema failed for schema not exist.")
 	}
 	return &discovery.GetExistenceResponse{
 		Response:  discovery.CreateResponse(discovery.ResponseSuccess, "Schema exist."),
@@ -778,26 +756,18 @@ func (ds *MetadataManager) ExistSchema(ctx context.Context, request *discovery.G
 func (ds *MetadataManager) DeleteSchema(ctx context.Context, request *discovery.DeleteSchemaRequest) (*discovery.DeleteSchemaResponse, error) {
 	exist, err := ServiceExistID(ctx, request.ServiceId)
 	if err != nil {
-		return &discovery.DeleteSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrServiceNotExists, "DeleteSchema failed for get service failed."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrServiceNotExists, "DeleteSchema failed for get service failed.")
 	}
 	if !exist {
-		return &discovery.DeleteSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrServiceNotExists, "DeleteSchema failed for service not exist."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrServiceNotExists, "DeleteSchema failed for service not exist.")
 	}
 	filter := mutil.NewBasicFilter(ctx, mutil.ServiceID(request.ServiceId), mutil.SchemaID(request.SchemaId))
 	res, err := client.GetMongoClient().DocDelete(ctx, model.CollectionSchema, filter)
 	if err != nil {
-		return &discovery.DeleteSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrUnavailableBackend, "DeleteSchema failed for delete schema failed."),
-		}, err
+		return nil, discovery.NewError(discovery.ErrUnavailableBackend, "DeleteSchema failed for delete schema failed.")
 	}
 	if !res {
-		return &discovery.DeleteSchemaResponse{
-			Response: discovery.CreateResponse(discovery.ErrSchemaNotExists, "DeleteSchema failed for schema not exist."),
-		}, nil
+		return nil, discovery.NewError(discovery.ErrSchemaNotExists, "DeleteSchema failed for schema not exist.")
 	}
 	return &discovery.DeleteSchemaResponse{
 		Response: discovery.CreateResponse(discovery.ResponseSuccess, "Delete schema info successfully."),
@@ -816,13 +786,7 @@ func (ds *MetadataManager) ModifySchema(ctx context.Context, request *discovery.
 	err := ds.modifySchema(ctx, request.ServiceId, &schema)
 	if err != nil {
 		log.Error(fmt.Sprintf("modify schema[%s/%s] failed, operator: %s", serviceID, schemaID, remoteIP), err)
-		resp := &discovery.ModifySchemaResponse{
-			Response: discovery.CreateResponseWithSCErr(err),
-		}
-		if err.InternalError() {
-			return resp, err
-		}
-		return resp, nil
+		return nil, err
 	}
 	log.Info(fmt.Sprintf("modify schema[%s/%s] successfully, operator: %s", serviceID, schemaID, remoteIP))
 	return &discovery.ModifySchemaResponse{
@@ -835,15 +799,12 @@ func (ds *MetadataManager) ModifySchemas(ctx context.Context, request *discovery
 	svc, err := dao.GetService(ctx, filter)
 	if err != nil {
 		if errors.Is(err, datasource.ErrNoData) {
-			return &discovery.ModifySchemasResponse{Response: discovery.CreateResponse(discovery.ErrServiceNotExists, "Service not exist")}, nil
+			return nil, discovery.NewError(discovery.ErrServiceNotExists, "Service not exist")
 		}
-		return &discovery.ModifySchemasResponse{Response: discovery.CreateResponse(discovery.ErrInternal, err.Error())}, err
+		return nil, discovery.NewError(discovery.ErrInternal, err.Error())
 	}
 	if respErr := ds.modifySchemas(ctx, svc.Service, request.Schemas); respErr != nil {
-		response, err := datasource.WrapErrResponse(respErr)
-		return &discovery.ModifySchemasResponse{
-			Response: response,
-		}, err
+		return nil, respErr
 	}
 	return &discovery.ModifySchemasResponse{
 		Response: discovery.CreateResponse(discovery.ResponseSuccess, "modify schemas info success"),
@@ -984,7 +945,7 @@ func (ds *MetadataManager) modifySchemas(ctx context.Context, service *discovery
 
 // modifySchema will be modified in the following cases
 // 1.service have no relation --> update the schema && update the service
-// 2.service is editable && service have relation with the schema --> update the shema
+// 2.service is editable && service have relation with the schema --> update the schema
 // 3.service is editable && service have no relation with the schema --> update the schema && update the service
 // 4.service can't edit && service have relation with the schema && schema summary not exist --> update the schema
 func (ds *MetadataManager) modifySchema(ctx context.Context, serviceID string, schema *discovery.Schema) *errsvc.Error {
@@ -1034,8 +995,7 @@ func (ds *MetadataManager) modifySchema(ctx context.Context, serviceID string, s
 		}
 	} else {
 		if !isExist {
-			copy(newSchemas, microservice.Schemas)
-			newSchemas = append(newSchemas, schema.SchemaId)
+			newSchemas = append(microservice.Schemas, schema.SchemaId)
 		}
 	}
 	if len(newSchemas) != 0 {
diff --git a/datasource/schema_test.go b/datasource/schema_test.go
index 2973272..15a9d5c 100644
--- a/datasource/schema_test.go
+++ b/datasource/schema_test.go
@@ -21,15 +21,15 @@ import (
 	"strconv"
 	"testing"
 
-	"github.com/little-cui/etcdadpt"
-
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/etcd"
 	"github.com/apache/servicecomb-service-center/datasource/mongo"
 	"github.com/apache/servicecomb-service-center/pkg/log"
 	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	pb "github.com/go-chassis/cari/discovery"
+	"github.com/go-chassis/cari/pkg/errsvc"
 	"github.com/go-chassis/go-archaius"
+	"github.com/little-cui/etcdadpt"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -91,8 +91,9 @@ func TestSchema_Create(t *testing.T) {
 			ServiceId: serviceIdDev,
 			Schemas:   schemas,
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrNotEnoughQuota, resp.Response.GetCode())
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrNotEnoughQuota, testErr.Code)
 
 		log.Info("batch modify schemas 2")
 		resp, err = datasource.GetMetadataManager().ModifySchemas(getContext(), &pb.ModifySchemasRequest{
@@ -107,8 +108,9 @@ func TestSchema_Create(t *testing.T) {
 			ServiceId: serviceIdDev,
 			Schemas:   schemas,
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrNotEnoughQuota, resp.Response.GetCode())
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrNotEnoughQuota, testErr.Code)
 	})
 
 	t.Run("modify schemas, should pass", func(t *testing.T) {
@@ -431,8 +433,9 @@ func TestSchema_Create(t *testing.T) {
 			ServiceId: serviceIdPro1,
 			Schemas:   schemas,
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrUndefinedSchemaID, respModifySchemas.Response.GetCode())
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrUndefinedSchemaID, testErr.Code)
 
 		log.Info("schema edit allowed, add a schema with new schemaId, should pass")
 		localMicroServiceDs = genLocalDatasource(true).MetadataManager()
@@ -492,8 +495,9 @@ func TestSchema_Create(t *testing.T) {
 			Summary:   schemas[0].Summary,
 			Schema:    schemas[0].SchemaId,
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrModifySchemaNotAllow, respModifySchema.Response.GetCode())
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrModifySchemaNotAllow, testErr.Code)
 
 		log.Info("schema edit allowed, add a schema with new schemaId, should pass")
 		localMicroServiceDs = genLocalDatasource(true).MetadataManager()
@@ -700,26 +704,29 @@ func TestSchema_Get(t *testing.T) {
 
 	t.Run("test get when request is invalid", func(t *testing.T) {
 		log.Info("service does not exist")
-		respGetSchema, err := datasource.GetMetadataManager().GetSchema(getContext(), &pb.GetSchemaRequest{
+		_, err := datasource.GetMetadataManager().GetSchema(getContext(), &pb.GetSchemaRequest{
 			ServiceId: "none_exist_service",
 			SchemaId:  "com.huawei.test",
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrServiceNotExists, respGetSchema.Response.GetCode())
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
 
-		respGetAllSchemas, err := datasource.GetMetadataManager().GetAllSchemas(getContext(), &pb.GetAllSchemaRequest{
+		_, err = datasource.GetMetadataManager().GetAllSchemas(getContext(), &pb.GetAllSchemaRequest{
 			ServiceId: "none_exist_service",
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrServiceNotExists, respGetAllSchemas.Response.GetCode())
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
 
 		log.Info("schema id doest not exist")
-		respGetSchema, err = datasource.GetMetadataManager().GetSchema(getContext(), &pb.GetSchemaRequest{
+		_, err = datasource.GetMetadataManager().GetSchema(getContext(), &pb.GetSchemaRequest{
 			ServiceId: serviceId,
 			SchemaId:  "none_exist_schema",
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrSchemaNotExists, respGetSchema.Response.GetCode())
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
 	})
 
 	t.Run("test get when request is valid", func(t *testing.T) {
@@ -766,44 +773,47 @@ func TestSchema_Delete(t *testing.T) {
 
 	t.Run("test delete when request is invalid", func(t *testing.T) {
 		log.Info("schema id does not exist")
-		resp, err := datasource.GetMetadataManager().DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+		_, err := datasource.GetMetadataManager().DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
 			ServiceId: serviceId,
 			SchemaId:  "none_exist_schema",
 		})
-		assert.NoError(t, err)
-		assert.NotEqual(t, pb.ResponseSuccess, resp.Response.GetCode())
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
 
 		log.Info("service id does not exist")
-		resp, err = datasource.GetMetadataManager().DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+		_, err = datasource.GetMetadataManager().DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
 			ServiceId: "not_exist_service",
 			SchemaId:  "com.huawei.test.ms",
 		})
-		assert.NoError(t, err)
-		assert.NotEqual(t, pb.ResponseSuccess, resp.Response.GetCode())
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
 	})
 
 	t.Run("test delete when request is valid", func(t *testing.T) {
-		resp, err := datasource.GetMetadataManager().DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+		_, err := datasource.GetMetadataManager().DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
 			ServiceId: serviceId,
 			SchemaId:  "com.huawei.test.ms",
 		})
 		assert.NoError(t, err)
-		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
 
-		respGet, err := datasource.GetMetadataManager().GetSchema(getContext(), &pb.GetSchemaRequest{
+		_, err = datasource.GetMetadataManager().GetSchema(getContext(), &pb.GetSchemaRequest{
 			ServiceId: serviceId,
 			SchemaId:  "com.huawei.test.ms",
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrSchemaNotExists, respGet.Response.GetCode())
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
 
-		respExist, err := datasource.GetMetadataManager().ExistSchema(getContext(), &pb.GetExistenceRequest{
+		_, err = datasource.GetMetadataManager().ExistSchema(getContext(), &pb.GetExistenceRequest{
 			Type:      "schema",
 			ServiceId: serviceId,
 			SchemaId:  "com.huawei.test.ms",
 		})
-		assert.NoError(t, err)
-		assert.Equal(t, pb.ErrSchemaNotExists, respExist.Response.GetCode())
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
 	})
 }
 
diff --git a/pkg/proto/service.go b/pkg/proto/service.go
index 1cf5faf..98f7b64 100644
--- a/pkg/proto/service.go
+++ b/pkg/proto/service.go
@@ -37,11 +37,6 @@ type ServiceCtrlServer interface {
 	GetTags(context.Context, *discovery.GetServiceTagsRequest) (*discovery.GetServiceTagsResponse, error)
 	UpdateTag(context.Context, *discovery.UpdateServiceTagRequest) (*discovery.UpdateServiceTagResponse, error)
 	DeleteTags(context.Context, *discovery.DeleteServiceTagsRequest) (*discovery.DeleteServiceTagsResponse, error)
-	GetSchemaInfo(context.Context, *discovery.GetSchemaRequest) (*discovery.GetSchemaResponse, error)
-	GetAllSchemaInfo(context.Context, *discovery.GetAllSchemaRequest) (*discovery.GetAllSchemaResponse, error)
-	DeleteSchema(context.Context, *discovery.DeleteSchemaRequest) (*discovery.DeleteSchemaResponse, error)
-	ModifySchema(context.Context, *discovery.ModifySchemaRequest) (*discovery.ModifySchemaResponse, error)
-	ModifySchemas(context.Context, *discovery.ModifySchemasRequest) (*discovery.ModifySchemasResponse, error)
 	AddDependenciesForMicroServices(context.Context, *discovery.AddDependenciesRequest) (*discovery.AddDependenciesResponse, error)
 	CreateDependenciesForMicroServices(context.Context, *discovery.CreateDependenciesRequest) (*discovery.CreateDependenciesResponse, error)
 	GetProviderDependencies(context.Context, *discovery.GetDependenciesRequest) (*discovery.GetProDependenciesResponse, error)
diff --git a/server/plugin/quota/quota.go b/server/plugin/quota/quota.go
index 4437c16..38865ca 100644
--- a/server/plugin/quota/quota.go
+++ b/server/plugin/quota/quota.go
@@ -123,7 +123,7 @@ func Apply(ctx context.Context, res *ApplyQuotaResource) error {
 	curNum, err := GetResourceUsage(ctx, res)
 	if err != nil {
 		log.Error(fmt.Sprintf("%s quota check failed", res.QuotaType), err)
-		return pb.NewError(pb.ErrInternal, err.Error())
+		return err
 	}
 	if curNum+res.QuotaSize > limitQuota {
 		mes := fmt.Sprintf("no quota to create %s, max num is %d, curNum is %d, apply num is %d",
diff --git a/server/rest/controller/v4/schema_controller.go b/server/resource/disco/schema_resource.go
similarity index 68%
rename from server/rest/controller/v4/schema_controller.go
rename to server/resource/disco/schema_resource.go
index 739e81e..3c08632 100644
--- a/server/rest/controller/v4/schema_controller.go
+++ b/server/resource/disco/schema_resource.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package v4
+package disco
 
 import (
 	"encoding/json"
@@ -29,26 +29,26 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/rest"
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/config"
-	"github.com/apache/servicecomb-service-center/server/core"
+	discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
 	pb "github.com/go-chassis/cari/discovery"
 )
 
 var errModifySchemaDisabled = errors.New("schema modify is disabled")
 
-type SchemaService struct {
+type SchemaResource struct {
 	//
 }
 
-func (s *SchemaService) URLPatterns() []rest.Route {
+func (s *SchemaResource) URLPatterns() []rest.Route {
 	var r = []rest.Route{
-		{Method: http.MethodGet, Path: "/v4/:project/registry/microservices/:serviceId/schemas/:schemaId", Func: s.GetSchemas},
-		{Method: http.MethodDelete, Path: "/v4/:project/registry/microservices/:serviceId/schemas/:schemaId", Func: s.DeleteSchemas},
-		{Method: http.MethodPost, Path: "/v4/:project/registry/microservices/:serviceId/schemas", Func: s.ModifySchemas},
-		{Method: http.MethodGet, Path: "/v4/:project/registry/microservices/:serviceId/schemas", Func: s.GetAllSchemas},
+		{Method: http.MethodGet, Path: "/v4/:project/registry/microservices/:serviceId/schemas/:schemaId", Func: s.GetSchema},
+		{Method: http.MethodDelete, Path: "/v4/:project/registry/microservices/:serviceId/schemas/:schemaId", Func: s.DeleteSchema},
+		{Method: http.MethodPost, Path: "/v4/:project/registry/microservices/:serviceId/schemas", Func: s.PutSchemas},
+		{Method: http.MethodGet, Path: "/v4/:project/registry/microservices/:serviceId/schemas", Func: s.ListSchema},
 	}
 
 	if !config.GetRegistry().SchemaDisable {
-		r = append(r, rest.Route{Method: http.MethodPut, Path: "/v4/:project/registry/microservices/:serviceId/schemas/:schemaId", Func: s.ModifySchema})
+		r = append(r, rest.Route{Method: http.MethodPut, Path: "/v4/:project/registry/microservices/:serviceId/schemas/:schemaId", Func: s.PutSchema})
 	} else {
 		r = append(r, rest.Route{Method: http.MethodPut, Path: "/v4/:project/registry/microservices/:serviceId/schemas/:schemaId", Func: s.DisableSchema})
 	}
@@ -56,23 +56,28 @@ func (s *SchemaService) URLPatterns() []rest.Route {
 	return r
 }
 
-func (s *SchemaService) DisableSchema(w http.ResponseWriter, r *http.Request) {
+func (s *SchemaResource) DisableSchema(w http.ResponseWriter, r *http.Request) {
 	rest.WriteError(w, pb.ErrForbidden, errModifySchemaDisabled.Error())
 }
 
-func (s *SchemaService) GetSchemas(w http.ResponseWriter, r *http.Request) {
+func (s *SchemaResource) GetSchema(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()
 	request := &pb.GetSchemaRequest{
 		ServiceId: query.Get(":serviceId"),
 		SchemaId:  query.Get(":schemaId"),
 	}
-	resp, _ := core.ServiceAPI.GetSchemaInfo(r.Context(), request)
+	resp, err := discosvc.GetSchema(r.Context(), request)
+	if err != nil {
+		log.Error("get schema failed", err)
+		rest.WriteServiceError(w, err)
+		return
+	}
 	w.Header().Add("X-Schema-Summary", resp.SchemaSummary)
 	resp.SchemaSummary = ""
-	rest.WriteResponse(w, r, resp.Response, resp)
+	rest.WriteResponse(w, r, nil, resp)
 }
 
-func (s *SchemaService) ModifySchema(w http.ResponseWriter, r *http.Request) {
+func (s *SchemaResource) PutSchema(w http.ResponseWriter, r *http.Request) {
 	message, err := ioutil.ReadAll(r.Body)
 	if err != nil {
 		log.Error("read body failed", err)
@@ -90,16 +95,16 @@ func (s *SchemaService) ModifySchema(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()
 	request.ServiceId = query.Get(":serviceId")
 	request.SchemaId = query.Get(":schemaId")
-	resp, err := core.ServiceAPI.ModifySchema(r.Context(), request)
-	if err != nil {
-		log.Error("can not update schema", err)
-		rest.WriteError(w, pb.ErrInternal, "can not update schema")
+	_, svcErr := discosvc.PutSchema(r.Context(), request)
+	if svcErr != nil {
+		log.Error("put schema failed", svcErr)
+		rest.WriteServiceError(w, svcErr)
 		return
 	}
-	rest.WriteResponse(w, r, resp.Response, nil)
+	rest.WriteResponse(w, r, nil, nil)
 }
 
-func (s *SchemaService) ModifySchemas(w http.ResponseWriter, r *http.Request) {
+func (s *SchemaResource) PutSchemas(w http.ResponseWriter, r *http.Request) {
 	message, err := ioutil.ReadAll(r.Body)
 	if err != nil {
 		log.Error("read body failed", err)
@@ -115,26 +120,31 @@ func (s *SchemaService) ModifySchemas(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	request.ServiceId = serviceID
-	resp, err := core.ServiceAPI.ModifySchemas(r.Context(), request)
-	if err != nil {
-		log.Error("can not update schema", err)
-		rest.WriteError(w, pb.ErrInternal, "can not update schema")
+	_, svcErr := discosvc.PutSchemas(r.Context(), request)
+	if svcErr != nil {
+		log.Error("put all schemas failed", svcErr)
+		rest.WriteServiceError(w, svcErr)
 		return
 	}
-	rest.WriteResponse(w, r, resp.Response, nil)
+	rest.WriteResponse(w, r, nil, nil)
 }
 
-func (s *SchemaService) DeleteSchemas(w http.ResponseWriter, r *http.Request) {
+func (s *SchemaResource) DeleteSchema(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()
 	request := &pb.DeleteSchemaRequest{
 		ServiceId: query.Get(":serviceId"),
 		SchemaId:  query.Get(":schemaId"),
 	}
-	resp, _ := core.ServiceAPI.DeleteSchema(r.Context(), request)
-	rest.WriteResponse(w, r, resp.Response, nil)
+	_, err := discosvc.DeleteSchema(r.Context(), request)
+	if err != nil {
+		log.Error("delete schema failed", err)
+		rest.WriteServiceError(w, err)
+		return
+	}
+	rest.WriteResponse(w, r, nil, nil)
 }
 
-func (s *SchemaService) GetAllSchemas(w http.ResponseWriter, r *http.Request) {
+func (s *SchemaResource) ListSchema(w http.ResponseWriter, r *http.Request) {
 	query := r.URL.Query()
 	withSchema := query.Get("withSchema")
 	serviceID := query.Get(":serviceId")
@@ -146,6 +156,11 @@ func (s *SchemaService) GetAllSchemas(w http.ResponseWriter, r *http.Request) {
 		ServiceId:  serviceID,
 		WithSchema: withSchema == "1",
 	}
-	resp, _ := core.ServiceAPI.GetAllSchemaInfo(r.Context(), request)
-	rest.WriteResponse(w, r, resp.Response, resp)
+	resp, err := discosvc.ListSchema(r.Context(), request)
+	if err != nil {
+		log.Error("list schema failed", err)
+		rest.WriteServiceError(w, err)
+		return
+	}
+	rest.WriteResponse(w, r, nil, resp)
 }
diff --git a/server/resource/disco/schema_resource_test.go b/server/resource/disco/schema_resource_test.go
new file mode 100644
index 0000000..b058995
--- /dev/null
+++ b/server/resource/disco/schema_resource_test.go
@@ -0,0 +1,268 @@
+/*
+ * 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 disco_test
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"io/ioutil"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/apache/servicecomb-service-center/pkg/util"
+	_ "github.com/apache/servicecomb-service-center/test"
+
+	"github.com/apache/servicecomb-service-center/pkg/rest"
+	"github.com/apache/servicecomb-service-center/server/resource/disco"
+	discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
+	pb "github.com/go-chassis/cari/discovery"
+	"github.com/stretchr/testify/assert"
+)
+
+func init() {
+	rest.RegisterServant(&disco.SchemaResource{})
+}
+
+func TestSchemaRouter_PutSchema(t *testing.T) {
+	ctx := context.TODO()
+
+	service, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{Service: &pb.MicroService{
+		ServiceName: "put_schema",
+		Schemas:     []string{"1"},
+	}})
+	assert.NoError(t, err)
+	serviceID := service.ServiceId
+	defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceID})
+
+	t.Run("put schema, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schema": "xxx",
+  "summary": "hash"
+}`
+		r, _ := http.NewRequest(http.MethodPut, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+	})
+
+	t.Run("put schema again, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schema": "yyy"
+}`
+		r, _ := http.NewRequest(http.MethodPut, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+	})
+
+	t.Run("put a new schema, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schema": "zzz"
+}`
+		r, _ := http.NewRequest(http.MethodPut, "/v4/default/registry/microservices/"+serviceID+"/schemas/2", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+
+		service, err := discosvc.GetService(util.WithNoCache(ctx), &pb.GetServiceRequest{ServiceId: serviceID})
+		assert.NoError(t, err)
+		assert.Equal(t, []string{"1", "2"}, service.Schemas)
+	})
+
+	t.Run("put an invalid schema, should failed", func(t *testing.T) {
+		requestBody := ``
+		r, _ := http.NewRequest(http.MethodPut, "/v4/default/registry/microservices/"+serviceID+"/schemas/2", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusBadRequest, w.Code)
+	})
+}
+
+func TestSchemaRouter_GetSchema(t *testing.T) {
+	ctx := context.TODO()
+
+	service, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{Service: &pb.MicroService{
+		ServiceName: "get_schema",
+		Schemas:     []string{"1"},
+	}})
+	assert.NoError(t, err)
+	serviceID := service.ServiceId
+	defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceID})
+
+	t.Run("get a not exist schema, should failed", func(t *testing.T) {
+		r, _ := http.NewRequest(http.MethodGet, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", nil)
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusBadRequest, w.Code)
+	})
+
+	t.Run("get schema, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schema": "xxx",
+  "summary": "hash"
+}`
+		r, _ := http.NewRequest(http.MethodPut, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+
+		r, _ = http.NewRequest(http.MethodGet, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", nil)
+		w = httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+
+		var resp pb.GetSchemaResponse
+		body, _ := ioutil.ReadAll(w.Body)
+		err := json.Unmarshal(body, &resp)
+		assert.NoError(t, err)
+		assert.Equal(t, "xxx", resp.Schema)
+		assert.Empty(t, resp.SchemaSummary)
+		assert.Equal(t, "hash", w.Header().Get("X-Schema-Summary"))
+	})
+}
+
+func TestSchemaRouter_DeleteSchema(t *testing.T) {
+	ctx := context.TODO()
+
+	service, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{Service: &pb.MicroService{
+		ServiceName: "delete_schema",
+		Schemas:     []string{"1"},
+	}})
+	assert.NoError(t, err)
+	serviceID := service.ServiceId
+	defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceID})
+
+	t.Run("delete a not exist schema, should failed", func(t *testing.T) {
+		r, _ := http.NewRequest(http.MethodDelete, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", nil)
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusBadRequest, w.Code)
+	})
+
+	t.Run("delete schema, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schema": "xxx",
+  "summary": "hash"
+}`
+		r, _ := http.NewRequest(http.MethodPut, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+
+		r, _ = http.NewRequest(http.MethodDelete, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", nil)
+		w = httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+
+		r, _ = http.NewRequest(http.MethodGet, "/v4/default/registry/microservices/"+serviceID+"/schemas/1", nil)
+		w = httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusBadRequest, w.Code)
+	})
+}
+
+func TestSchemaRouter_PutSchemas(t *testing.T) {
+	ctx := context.TODO()
+
+	service, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{Service: &pb.MicroService{
+		ServiceName: "put_schema",
+		Schemas:     []string{"1"},
+	}})
+	assert.NoError(t, err)
+	serviceID := service.ServiceId
+	defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceID})
+
+	t.Run("put schemas, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schemas": [
+    {
+      "schemaId": "1",
+      "schema": "xxx",
+      "summary": "hash"
+    }
+  ]
+}`
+		r, _ := http.NewRequest(http.MethodPost, "/v4/default/registry/microservices/"+serviceID+"/schemas", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+	})
+
+	t.Run("put schemas again, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schemas": [
+    {
+      "schemaId": "1",
+      "schema": "yyy",
+      "summary": "hash"
+    }
+  ]
+}`
+		r, _ := http.NewRequest(http.MethodPost, "/v4/default/registry/microservices/"+serviceID+"/schemas", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+	})
+
+	t.Run("put new schemas, should ok", func(t *testing.T) {
+		requestBody := `{
+  "schemas": [
+    {
+      "schemaId": "2",
+      "schema": "zzz",
+      "summary": "hash"
+    }
+  ]
+}`
+		r, _ := http.NewRequest(http.MethodPost, "/v4/default/registry/microservices/"+serviceID+"/schemas", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusOK, w.Code)
+
+		service, err := discosvc.GetService(util.WithNoCache(ctx), &pb.GetServiceRequest{ServiceId: serviceID})
+		assert.NoError(t, err)
+		assert.Equal(t, []string{"2"}, service.Schemas)
+	})
+
+	t.Run("put an invalid schema, should failed", func(t *testing.T) {
+		requestBody := `{
+  "schemas": []
+}`
+		r, _ := http.NewRequest(http.MethodPost, "/v4/default/registry/microservices/"+serviceID+"/schemas", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusBadRequest, w.Code)
+	})
+
+	t.Run("put schemas without summary, should failed", func(t *testing.T) {
+		requestBody := `{
+  "schemas": [
+    {
+      "schemaId": "2",
+      "schema": "zzz"
+    }
+  ]
+}`
+		r, _ := http.NewRequest(http.MethodPost, "/v4/default/registry/microservices/"+serviceID+"/schemas", bytes.NewBufferString(requestBody))
+		w := httptest.NewRecorder()
+		rest.GetRouter().ServeHTTP(w, r)
+		assert.Equal(t, http.StatusBadRequest, w.Code)
+	})
+}
diff --git a/server/resource/register.go b/server/resource/register.go
index 95cf329..81b1294 100644
--- a/server/resource/register.go
+++ b/server/resource/register.go
@@ -19,6 +19,7 @@ package resource
 
 import (
 	roa "github.com/apache/servicecomb-service-center/pkg/rest"
+	"github.com/apache/servicecomb-service-center/server/resource/disco"
 	"github.com/apache/servicecomb-service-center/server/resource/gov"
 	"github.com/apache/servicecomb-service-center/server/resource/govern"
 	"github.com/apache/servicecomb-service-center/server/resource/rbac"
@@ -34,6 +35,7 @@ func initRouter() {
 		roa.RegisterServant(&rbac.AuthResource{})
 		roa.RegisterServant(&rbac.RoleResource{})
 	}
+	roa.RegisterServant(&disco.SchemaResource{})
 	roa.RegisterServant(&gov.Governance{})
 	roa.RegisterServant(&govern.Resource{})
 }
diff --git a/server/rest/controller/v3/schema_controller.go b/server/rest/controller/v3/schema_controller.go
index a3b2b1c..62512ae 100644
--- a/server/rest/controller/v3/schema_controller.go
+++ b/server/rest/controller/v3/schema_controller.go
@@ -20,19 +20,19 @@ import (
 	"net/http"
 
 	"github.com/apache/servicecomb-service-center/pkg/rest"
-	v4 "github.com/apache/servicecomb-service-center/server/rest/controller/v4"
+	v4 "github.com/apache/servicecomb-service-center/server/resource/disco"
 )
 
 type SchemaService struct {
-	v4.SchemaService
+	v4.SchemaResource
 }
 
 func (this *SchemaService) URLPatterns() []rest.Route {
 	return []rest.Route{
-		{http.MethodGet, "/registry/v3/microservices/:serviceId/schemas/:schemaId", this.GetSchemas},
-		{http.MethodPut, "/registry/v3/microservices/:serviceId/schemas/:schemaId", this.ModifySchema},
-		{http.MethodDelete, "/registry/v3/microservices/:serviceId/schemas/:schemaId", this.DeleteSchemas},
-		{http.MethodPost, "/registry/v3/microservices/:serviceId/schemas", this.ModifySchemas},
-		{http.MethodGet, "/registry/v3/microservices/:serviceId/schemas", this.GetAllSchemas},
+		{http.MethodGet, "/registry/v3/microservices/:serviceId/schemas/:schemaId", this.GetSchema},
+		{http.MethodPut, "/registry/v3/microservices/:serviceId/schemas/:schemaId", this.PutSchema},
+		{http.MethodDelete, "/registry/v3/microservices/:serviceId/schemas/:schemaId", this.DeleteSchema},
+		{http.MethodPost, "/registry/v3/microservices/:serviceId/schemas", this.PutSchemas},
+		{http.MethodGet, "/registry/v3/microservices/:serviceId/schemas", this.ListSchema},
 	}
 }
diff --git a/server/rest/controller/v4/v4.go b/server/rest/controller/v4/v4.go
index 2c3e022..9e49b91 100644
--- a/server/rest/controller/v4/v4.go
+++ b/server/rest/controller/v4/v4.go
@@ -28,7 +28,6 @@ func init() {
 func initRouter() {
 	roa.RegisterServant(&MainService{})
 	roa.RegisterServant(&MicroServiceService{})
-	roa.RegisterServant(&SchemaService{})
 	roa.RegisterServant(&DependencyService{})
 	roa.RegisterServant(&TagService{})
 	roa.RegisterServant(&MicroServiceInstanceService{})
diff --git a/server/service/disco/schema.go b/server/service/disco/schema.go
index 5467118..a9275ae 100644
--- a/server/service/disco/schema.go
+++ b/server/service/disco/schema.go
@@ -29,44 +29,38 @@ import (
 	pb "github.com/go-chassis/cari/discovery"
 )
 
-func (s *MicroServiceService) GetSchemaInfo(ctx context.Context, in *pb.GetSchemaRequest) (*pb.GetSchemaResponse, error) {
+func GetSchema(ctx context.Context, in *pb.GetSchemaRequest) (*pb.GetSchemaResponse, error) {
 	err := validator.Validate(in)
 	if err != nil {
 		log.Error(fmt.Sprintf("get schema[%s/%s] failed", in.ServiceId, in.SchemaId), nil)
-		return &pb.GetSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrInvalidParams, err.Error()),
-		}, nil
+		return nil, pb.NewError(pb.ErrInvalidParams, err.Error())
 	}
 
 	return datasource.GetMetadataManager().GetSchema(ctx, in)
 }
 
-func (s *MicroServiceService) GetAllSchemaInfo(ctx context.Context, in *pb.GetAllSchemaRequest) (*pb.GetAllSchemaResponse, error) {
+func ListSchema(ctx context.Context, in *pb.GetAllSchemaRequest) (*pb.GetAllSchemaResponse, error) {
 	err := validator.Validate(in)
 	if err != nil {
 		log.Error(fmt.Sprintf("get service[%s] all schemas failed", in.ServiceId), nil)
-		return &pb.GetAllSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrInvalidParams, err.Error()),
-		}, nil
+		return nil, pb.NewError(pb.ErrInvalidParams, err.Error())
 	}
 
 	return datasource.GetMetadataManager().GetAllSchemas(ctx, in)
 }
 
-func (s *MicroServiceService) DeleteSchema(ctx context.Context, in *pb.DeleteSchemaRequest) (*pb.DeleteSchemaResponse, error) {
+func DeleteSchema(ctx context.Context, in *pb.DeleteSchemaRequest) (*pb.DeleteSchemaResponse, error) {
 	err := validator.Validate(in)
 	if err != nil {
 		remoteIP := util.GetIPFromContext(ctx)
 		log.Error(fmt.Sprintf("delete schema[%s/%s] failed, operator: %s", in.ServiceId, in.SchemaId, remoteIP), err)
-		return &pb.DeleteSchemaResponse{
-			Response: pb.CreateResponse(pb.ErrInvalidParams, err.Error()),
-		}, nil
+		return nil, pb.NewError(pb.ErrInvalidParams, err.Error())
 	}
 
 	return datasource.GetMetadataManager().DeleteSchema(ctx, in)
 }
 
-// ModifySchemas covers all the schemas of a service.
+// PutSchemas covers all the schemas of a service.
 // To cover the old schemas, ModifySchemas adds new schemas into, delete and
 // modify the old schemas.
 // 1. When the service is in production environment and schema is not editable:
@@ -78,19 +72,17 @@ func (s *MicroServiceService) DeleteSchema(ctx context.Context, in *pb.DeleteSch
 // If the request contains a new schemaID,
 // the new schemaID will be automatically added to the service information.
 // Schema is allowed to add/delete/modify.
-func (s *MicroServiceService) ModifySchemas(ctx context.Context, in *pb.ModifySchemasRequest) (*pb.ModifySchemasResponse, error) {
+func PutSchemas(ctx context.Context, in *pb.ModifySchemasRequest) (*pb.ModifySchemasResponse, error) {
 	err := validator.Validate(in)
 	if err != nil {
 		remoteIP := util.GetIPFromContext(ctx)
 		log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", in.ServiceId, remoteIP), err)
-		return &pb.ModifySchemasResponse{
-			Response: pb.CreateResponse(pb.ErrInvalidParams, "Invalid request."),
-		}, nil
+		return nil, pb.NewError(pb.ErrInvalidParams, "Invalid request.")
 	}
 	return datasource.GetMetadataManager().ModifySchemas(ctx, in)
 }
 
-// ModifySchema modifies a specific schema
+// PutSchema modifies a specific schema
 // 1. When the service is in production environment and schema is not editable:
 // If the request contains a new schemaID (the number of schemaIDs of
 // the service is also required to be 0, or the request will be rejected),
@@ -100,20 +92,17 @@ func (s *MicroServiceService) ModifySchemas(ctx context.Context, in *pb.ModifySc
 // If the request contains a new schemaID,
 // the new schemaID will be automatically added to the service information.
 // Schema is allowed to add/modify.
-func (s *MicroServiceService) ModifySchema(ctx context.Context, request *pb.ModifySchemaRequest) (*pb.ModifySchemaResponse, error) {
+func PutSchema(ctx context.Context, request *pb.ModifySchemaRequest) (*pb.ModifySchemaResponse, error) {
 	domainProject := util.ParseDomainProject(ctx)
-	respErr := s.canModifySchema(ctx, domainProject, request)
-	if respErr != nil {
-		response, err := datasource.WrapErrResponse(respErr)
-		return &pb.ModifySchemaResponse{
-			Response: response,
-		}, err
+	err := canModifySchema(ctx, domainProject, request)
+	if err != nil {
+		return nil, err
 	}
 
 	return datasource.GetMetadataManager().ModifySchema(ctx, request)
 }
 
-func (s *MicroServiceService) canModifySchema(ctx context.Context, domainProject string, in *pb.ModifySchemaRequest) error {
+func canModifySchema(ctx context.Context, domainProject string, in *pb.ModifySchemaRequest) error {
 	remoteIP := util.GetIPFromContext(ctx)
 	serviceID := in.ServiceId
 	schemaID := in.SchemaId
diff --git a/server/service/disco/schema_test.go b/server/service/disco/schema_test.go
index f9d87b3..5c64a8d 100644
--- a/server/service/disco/schema_test.go
+++ b/server/service/disco/schema_test.go
@@ -19,14 +19,14 @@ package disco_test
 import (
 	"strconv"
 	"strings"
-
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
+	"testing"
 
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/server/plugin/quota"
 	"github.com/apache/servicecomb-service-center/server/service/disco"
 	pb "github.com/go-chassis/cari/discovery"
+	"github.com/go-chassis/cari/pkg/errsvc"
+	"github.com/stretchr/testify/assert"
 )
 
 const (
@@ -37,879 +37,868 @@ var (
 	TOO_LONG_SUMMARY = strings.Repeat("x", 129)
 )
 
-var _ = Describe("'Schema' service", func() {
-	Describe("execute 'create' operation", func() {
-		var (
-			serviceIdDev string
-			serviceId    string
-		)
-
-		It("should be passed, create service", func() {
-			respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-				Service: &pb.MicroService{
-					AppId:       "create_schema_group",
-					ServiceName: "create_schema_service",
-					Version:     "1.0.0",
-					Level:       "FRONT",
-					Status:      pb.MS_UP,
-					Environment: pb.ENV_DEV,
+func TestPutSchema(t *testing.T) {
+	var (
+		serviceIdDev string
+		serviceId    string
+	)
+
+	t.Run("should be passed, create service", func(t *testing.T) {
+		respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				AppId:       "create_schema_group",
+				ServiceName: "create_schema_service",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Status:      pb.MS_UP,
+				Environment: pb.ENV_DEV,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+		serviceIdDev = respCreateService.ServiceId
+
+		respCreateService, err = serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				AppId:       "create_schema_group",
+				ServiceName: "create_schema_service",
+				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())
+		serviceId = respCreateService.ServiceId
+	})
+
+	defer func() {
+		serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceIdDev, Force: true})
+		serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceId, Force: true})
+	}()
+
+	f := func() {
+		_, err := disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+			ServiceId: "",
+			SchemaId:  "com.huawei.test",
+			Schema:    "create schema",
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+			ServiceId: "notExistService",
+			SchemaId:  "com.huawei.test",
+			Schema:    "create schema",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
+
+		_, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+			ServiceId: serviceIdDev,
+			SchemaId:  invalidSchemaId,
+			Schema:    "create schema",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+			ServiceId: serviceIdDev,
+			SchemaId:  "com.huawei.test",
+			Schema:    "create schema",
+			Summary:   TOO_LONG_SUMMARY,
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+			ServiceId: serviceIdDev,
+			SchemaId:  "com.huawei.test",
+			Schema:    "create schema",
+			Summary:   "_",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+	}
+
+	t.Run("should be failed in prod env, when create an invalid schema", func(t *testing.T) {
+		old := serviceIdDev
+		serviceIdDev = serviceId
+		f()
+		serviceIdDev = old
+	})
+
+	t.Run("should be failed in dev env, when create an invalid schema", func(t *testing.T) {
+		f()
+	})
+
+	f = func() {
+		_, err := disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: "",
+			Schemas: []*pb.Schema{
+				{
+					SchemaId: "com.huawei.test",
+					Summary:  "create schema",
+					Schema:   "create schema",
 				},
-			})
-			Expect(err).To(BeNil())
-			Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			serviceIdDev = respCreateService.ServiceId
-
-			respCreateService, err = serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-				Service: &pb.MicroService{
-					AppId:       "create_schema_group",
-					ServiceName: "create_schema_service",
-					Version:     "1.0.0",
-					Level:       "FRONT",
-					Status:      pb.MS_UP,
-					Environment: pb.ENV_PROD,
+			},
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+			Schemas: []*pb.Schema{
+				{
+					SchemaId: invalidSchemaId,
+					Summary:  "create schema",
+					Schema:   "create schema",
 				},
-			})
-			Expect(err).To(BeNil())
-			Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			serviceId = respCreateService.ServiceId
-		})
-
-		Context("when create an invalid schema", func() {
-			f := func() {
-				By("service id is empty")
-				resp, err := serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-					ServiceId: "",
-					SchemaId:  "com.huawei.test",
-					Schema:    "create schema",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("service does not exist")
-				resp, err = serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-					ServiceId: "notExistService",
-					SchemaId:  "com.huawei.test",
-					Schema:    "create schema",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrServiceNotExists))
-
-				By("schema id is invalid")
-				resp, err = serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-					ServiceId: serviceIdDev,
-					SchemaId:  invalidSchemaId,
-					Schema:    "create schema",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("summary is invalid")
-				resp, err = serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-					ServiceId: serviceIdDev,
-					SchemaId:  "com.huawei.test",
-					Schema:    "create schema",
-					Summary:   TOO_LONG_SUMMARY,
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				resp, err = serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-					ServiceId: serviceIdDev,
-					SchemaId:  "com.huawei.test",
-					Schema:    "create schema",
-					Summary:   "_",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
+			},
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+			Schemas: []*pb.Schema{
+				{
+					SchemaId: "com.huawei.test",
+					Summary:  "create schema",
+				},
+			},
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+			Schemas: []*pb.Schema{
+				{
+					SchemaId: "com.huawei.test",
+					Schema:   "create schema",
+				},
+			},
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+			Schemas: []*pb.Schema{
+				{
+					SchemaId: "com.huawei.test",
+					Schema:   "create schema",
+					Summary:  TOO_LONG_SUMMARY,
+				},
+			},
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+	}
+
+	t.Run("should be failed in dev env, when batch create invalid schemas", func(t *testing.T) {
+		f()
+	})
+
+	t.Run("should be failed in prod env, when batch create invalid schemas", func(t *testing.T) {
+		old := serviceIdDev
+		serviceIdDev = serviceId
+		f()
+		serviceIdDev = old
+	})
+
+	size := quota.DefaultSchemaQuota + 1
+	schemaIds := make([]string, 0, size)
+	schemas := make([]*pb.Schema, 0, size)
+	for i := 0; i < size; i++ {
+		s := "ServiceCombTestTheLimitOfSchemas" + strconv.Itoa(i)
+
+		schemaIds = append(schemaIds, s)
+		schemas = append(schemas, &pb.Schema{
+			SchemaId: s,
+			Schema:   s,
+			Summary:  s,
+		})
+	}
+
+	t.Run("should be failed in dev env, when create schemas out of gauge", func(t *testing.T) {
+		_, err := disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+			Schemas:   schemas,
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+			Schemas:   schemas[:quota.DefaultSchemaQuota],
+		})
+		assert.NoError(t, err)
+
+		schema := schemas[quota.DefaultSchemaQuota]
+		_, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+			ServiceId: serviceIdDev,
+			SchemaId:  schema.SchemaId,
+			Schema:    schema.Schema,
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrNotEnoughQuota, testErr.Code)
+	})
+
+	t.Run("should be failed in prod env, when create schemas out of gauge", func(t *testing.T) {
+		_, err := disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev,
+			Schemas:   schemas,
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+	})
+
+	t.Run("should be failed when create service", func(t *testing.T) {
+		createServiceResponse, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				AppId:       "check_schema_group",
+				ServiceName: "check_schema_service",
+				Version:     "1.0.0",
+				Level:       "FRONT",
+				Schemas:     schemaIds,
+				Status:      pb.MS_UP,
+			},
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ErrInvalidParams, createServiceResponse.Response.GetCode())
+	})
+
+	var (
+		serviceIdPro string
+	)
+	respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			AppId:       "create_schemas_prod",
+			ServiceName: "create_schemas_service",
+			Version:     "1.0.1",
+			Level:       "FRONT",
+			Schemas: []string{
+				"first_schemaId",
+				"second_schemaId",
+			},
+			Status:      pb.MS_UP,
+			Environment: pb.ENV_PROD,
+		},
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	serviceIdPro = respCreateService.ServiceId
+	defer serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceIdPro, Force: true})
+
+	t.Run("should be failed, when modify schema and summary is empty", func(t *testing.T) {
+		respModifySchema, err := disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+			ServiceId: serviceIdPro,
+			SchemaId:  "first_schemaId",
+			Schema:    "first_schema",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respModifySchema.Response.GetCode())
+
+		schemas := []*pb.Schema{
+			{
+				SchemaId: "first_schemaId",
+				Schema:   "first_schema",
+				Summary:  "first0summary",
+			},
+		}
+		respModifySchemas, err := disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdPro,
+			Schemas:   schemas,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respModifySchemas.Response.GetCode())
+
+		respExist, err := serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:      datasource.ExistTypeSchema,
+			ServiceId: serviceIdPro,
+			SchemaId:  "first_schemaId",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, "first0summary", respExist.Summary)
+
+		schemas = []*pb.Schema{
+			{
+				SchemaId: "second_schemaId",
+				Schema:   "second_schema",
+				Summary:  "second0summary",
+			},
+		}
+		respModifySchemas, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdPro,
+			Schemas:   schemas,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respModifySchemas.Response.GetCode())
+	})
+}
+
+func TestPutSchemas(t *testing.T) {
+	var (
+		serviceIdDev1 string
+		serviceIdDev2 string
+	)
+	respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			AppId:       "create_schemas_dev",
+			ServiceName: "create_schemas_service",
+			Version:     "1.0.0",
+			Level:       "FRONT",
+			Status:      pb.MS_UP,
+			Environment: pb.ENV_DEV,
+		},
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	serviceIdDev1 = respCreateService.ServiceId
+	defer serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceIdDev1, Force: true})
+
+	respCreateService, err = serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			AppId:       "create_schemas_dev",
+			ServiceName: "create_schemas_service",
+			Version:     "1.0.1",
+			Level:       "FRONT",
+			Schemas: []string{
+				"first_schemaId",
+			},
+			Status:      pb.MS_UP,
+			Environment: pb.ENV_DEV,
+		},
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	serviceIdDev2 = respCreateService.ServiceId
+	defer serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceIdDev2, Force: true})
+
+	t.Run("should be passed, when create schemas when service schema id set is empty", func(t *testing.T) {
+		schemas := []*pb.Schema{
+			{
+				SchemaId: "first_schemaId",
+				Schema:   "first_schema",
+				Summary:  "first0summary",
+			},
+			{
+				SchemaId: "first_schemaId",
+				Schema:   "first_schema",
+				Summary:  "first0summary",
+			},
+		}
+		respCreateService, err := disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev1,
+			Schemas:   schemas,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+
+		respGetAllSchema, err := disco.ListSchema(getContext(), &pb.GetAllSchemaRequest{
+			ServiceId: serviceIdDev1,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respGetAllSchema.Response.GetCode())
+		assert.Equal(t, 1, len(respGetAllSchema.Schemas))
+
+		schemas = []*pb.Schema{}
+		respCreateService, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev2,
+			Schemas:   schemas,
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		schemas = []*pb.Schema{
+			{
+				SchemaId: "first_schemaId",
+				Schema:   "first_schema_change",
+				Summary:  "first0summary1change",
+			},
+		}
+		respCreateService, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev1,
+			Schemas:   schemas,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+
+		schemas = []*pb.Schema{
+			{
+				SchemaId: "second_schemaId",
+				Schema:   "second_schema",
+				Summary:  "second0summary",
+			},
+		}
+		respCreateService, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev1,
+			Schemas:   schemas,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+
+		service, err := disco.GetService(getContext(), &pb.GetServiceRequest{
+			ServiceId: serviceIdDev1,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, []string{"second_schemaId"}, service.Schemas)
+
+		schemas = []*pb.Schema{}
+		respCreateService, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev1,
+			Schemas:   schemas,
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		schemas = []*pb.Schema{
+			{
+				SchemaId: "second_schemaId",
+				Schema:   "second_schema",
+				Summary:  "second0summary",
+			},
+		}
+		respCreateService, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
+			ServiceId: serviceIdDev2,
+			Schemas:   schemas,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+
+		service, err = disco.GetService(getContext(), &pb.GetServiceRequest{
+			ServiceId: serviceIdDev2,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, []string{"second_schemaId"}, service.Schemas)
+	})
+}
+
+func TestExistSchema(t *testing.T) {
+	var (
+		serviceId string
+	)
+	respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			AppId:       "query_schema_group",
+			ServiceName: "query_schema_service",
+			Version:     "1.0.0",
+			Level:       "FRONT",
+			Status:      pb.MS_UP,
+			Environment: pb.ENV_DEV,
+		},
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	serviceId = respCreateService.ServiceId
+	defer serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceId, Force: true})
+
+	resp, err := disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+		ServiceId: serviceId,
+		SchemaId:  "com.huawei.test",
+		Schema:    "query schema",
+		Summary:   "summary",
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+
+	resp, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+		ServiceId: serviceId,
+		SchemaId:  "com.huawei.test.no.summary",
+		Schema:    "query schema",
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+
+	t.Run("should be failed, when request is invalid", func(t *testing.T) {
+		resp, err := serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:      "schema",
+			ServiceId: "",
+			SchemaId:  "com.huawei.test",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ErrInvalidParams, resp.Response.GetCode())
+
+		resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:      "schema",
+			ServiceId: serviceId,
+			SchemaId:  "noneschema",
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
+
+		resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:      "schema",
+			ServiceId: serviceId,
+			SchemaId:  TOO_LONG_SCHEMAID,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ErrInvalidParams, resp.Response.GetCode())
+	})
+
+	t.Run("should be passed, when request is valid", func(t *testing.T) {
+		resp, err := serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:      "schema",
+			ServiceId: serviceId,
+			SchemaId:  "com.huawei.test",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+		assert.Equal(t, "summary", resp.Summary)
+
+		resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:        "schema",
+			ServiceId:   serviceId,
+			SchemaId:    "com.huawei.test",
+			AppId:       "()",
+			ServiceName: "",
+			Version:     "()",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+
+		resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:      "schema",
+			ServiceId: serviceId,
+			SchemaId:  "com.huawei.test.no.summary",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+		assert.Equal(t, "com.huawei.test.no.summary", resp.SchemaId)
+		assert.Equal(t, "", resp.Summary)
+	})
+}
+
+func TestGetSchema(t *testing.T) {
+	var (
+		serviceId     string
+		serviceId1    string
+		schemaId1     string = "all_schema1"
+		schemaId2     string = "all_schema2"
+		schemaId3     string = "all_schema3"
+		summary       string = "this0is1a2test"
+		schemaContent string = "the content is vary large"
+	)
+
+	respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			AppId:       "get_schema_group",
+			ServiceName: "get_schema_service",
+			Version:     "1.0.0",
+			Level:       "FRONT",
+			Schemas: []string{
+				"non-schema-content",
+			},
+			Status:      pb.MS_UP,
+			Environment: pb.ENV_DEV,
+		},
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	serviceId = respCreateService.ServiceId
+	defer serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceId, Force: true})
+
+	respCreateService, err = serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			AppId:       "get_all_schema",
+			ServiceName: "get_all_schema",
+			Version:     "1.0.0",
+			Level:       "FRONT",
+			Schemas: []string{
+				schemaId1,
+				schemaId2,
+				schemaId3,
+			},
+			Status: pb.MS_UP,
+		},
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respCreateService.Response.GetCode())
+	serviceId1 = respCreateService.ServiceId
+	defer serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceId1, Force: true})
+
+	resp, err := disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+		ServiceId: serviceId,
+		SchemaId:  "com.huawei.test",
+		Schema:    "get schema",
+		Summary:   "schema0summary",
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+
+	respPutData, err := disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+		ServiceId: serviceId1,
+		SchemaId:  schemaId2,
+		Schema:    schemaContent,
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respPutData.Response.GetCode())
+
+	respPutData, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+		ServiceId: serviceId1,
+		SchemaId:  schemaId3,
+		Schema:    schemaContent,
+		Summary:   summary,
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, respPutData.Response.GetCode())
+
+	t.Run("should be pass, when list schema", func(t *testing.T) {
+		respGetAllSchema, err := disco.ListSchema(getContext(), &pb.GetAllSchemaRequest{
+			ServiceId:  serviceId1,
+			WithSchema: false,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respGetAllSchema.Response.GetCode())
+		schemas := respGetAllSchema.Schemas
+		for _, schema := range schemas {
+			if schema.SchemaId == schemaId1 {
+				assert.Empty(t, schema.Summary)
+				assert.Empty(t, schema.Schema)
+			}
+			if schema.SchemaId == schemaId2 {
+				assert.Empty(t, schema.Summary)
+				assert.Empty(t, schema.Schema)
 			}
+			if schema.SchemaId == schemaId3 {
+				assert.Equal(t, summary, schema.Summary)
+				assert.Empty(t, schema.Schema)
+			}
+		}
 
-			It("should be failed in prod env", func() {
-				old := serviceIdDev
-				serviceIdDev = serviceId
-				f()
-				serviceIdDev = old
-			})
-			It("should be failed in dev env", f)
-		})
-
-		Context("when batch create invalid schemas", func() {
-			f := func() {
-				By("service does not exist")
-				respCreateService, err := serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: "not_exist_serviceId",
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("service id is empty")
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: "",
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("schema id is invalid")
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev,
-					Schemas: []*pb.Schema{
-						{
-							SchemaId: invalidSchemaId,
-						},
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("schema is empty")
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev,
-					Schemas: []*pb.Schema{
-						{
-							SchemaId: "com.huawei.test",
-						},
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("summary is empty")
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev,
-					Schemas: []*pb.Schema{
-						{
-							SchemaId: "com.huawei.test",
-							Schema:   "create schema",
-						},
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("summery is invalid")
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev,
-					Schemas: []*pb.Schema{
-						{
-							SchemaId: "com.huawei.test",
-							Schema:   "create schema",
-							Summary:  TOO_LONG_SUMMARY,
-						},
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
+		respGetAllSchema, err = disco.ListSchema(getContext(), &pb.GetAllSchemaRequest{
+			ServiceId:  serviceId1,
+			WithSchema: true,
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respGetAllSchema.Response.GetCode())
+		schemas = respGetAllSchema.Schemas
+		for _, schema := range schemas {
+			if schema.SchemaId == schemaId1 {
+				assert.Empty(t, schema.Summary)
+				assert.Empty(t, schema.Schema)
 			}
-			It("should be failed in dev env", f)
-
-			It("should be failed in prod env", func() {
-				old := serviceIdDev
-				serviceIdDev = serviceId
-				f()
-				serviceIdDev = old
-			})
-		})
-
-		Context("when create schemas out of gauge", func() {
-			size := quota.DefaultSchemaQuota + 1
-			schemaIds := make([]string, 0, size)
-			schemas := make([]*pb.Schema, 0, size)
-			for i := 0; i < size; i++ {
-				s := "ServiceCombTestTheLimitOfSchemas" + strconv.Itoa(i)
-
-				schemaIds = append(schemaIds, s)
-				schemas = append(schemas, &pb.Schema{
-					SchemaId: s,
-					Schema:   s,
-					Summary:  s,
-				})
+			if schema.SchemaId == schemaId2 {
+				assert.Empty(t, schema.Summary)
+				assert.Equal(t, schemaContent, schema.Schema)
 			}
+			if schema.SchemaId == schemaId3 {
+				assert.Equal(t, summary, schema.Summary)
+				assert.Equal(t, schemaContent, schema.Schema)
+			}
+		}
+
+	})
+
+	t.Run("should be failed, when request is invalid", func(t *testing.T) {
+		_, err := disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: "noneexistservice",
+			SchemaId:  "com.huawei.test",
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
+
+		_, err = disco.ListSchema(getContext(), &pb.GetAllSchemaRequest{
+			ServiceId: "noneexistservice",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
+
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: "",
+			SchemaId:  "com.huawei.test",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.ListSchema(getContext(), &pb.GetAllSchemaRequest{
+			ServiceId: "",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: TOO_LONG_SERVICEID,
+			SchemaId:  "com.huawei.test",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.ListSchema(getContext(), &pb.GetAllSchemaRequest{
+			ServiceId: TOO_LONG_SERVICEID,
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  "nonexistschema",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
+
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  "",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  TOO_LONG_SCHEMAID,
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
+
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  invalidSchemaId,
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
-			It("should be failed in dev env", func() {
-				By("batch modify schemas 1")
-				respCreateSchemas, err := serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateSchemas.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("batch modify schemas 2")
-				respCreateSchemas, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev,
-					Schemas:   schemas[:quota.DefaultSchemaQuota],
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateSchemas.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				By("modify one schema")
-				respCreateService := &pb.ModifySchemaResponse{}
-				schema := schemas[quota.DefaultSchemaQuota]
-				respCreateService, err = serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-					ServiceId: serviceIdDev,
-					SchemaId:  schema.SchemaId,
-					Schema:    schema.Schema,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ErrNotEnoughQuota))
-			})
-
-			It("should be failed in prod env", func() {
-				respCreateService, err := serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-			})
-
-			It("should be failed when create service", func() {
-				respServiceForSchema, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-					Service: &pb.MicroService{
-						AppId:       "check_schema_group",
-						ServiceName: "check_schema_service",
-						Version:     "1.0.0",
-						Level:       "FRONT",
-						Schemas:     schemaIds,
-						Status:      pb.MS_UP,
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respServiceForSchema.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-			})
-		})
-
-		Context("when modify schemas", func() {
-			var (
-				serviceIdDev1 string
-				serviceIdDev2 string
-			)
-
-			It("should be passed", func() {
-				respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-					Service: &pb.MicroService{
-						AppId:       "create_schemas_dev",
-						ServiceName: "create_schemas_service",
-						Version:     "1.0.0",
-						Level:       "FRONT",
-						Status:      pb.MS_UP,
-						Environment: pb.ENV_DEV,
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-				serviceIdDev1 = respCreateService.ServiceId
-
-				respCreateService, err = serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-					Service: &pb.MicroService{
-						AppId:       "create_schemas_dev",
-						ServiceName: "create_schemas_service",
-						Version:     "1.0.1",
-						Level:       "FRONT",
-						Schemas: []string{
-							"first_schemaId",
-						},
-						Status:      pb.MS_UP,
-						Environment: pb.ENV_DEV,
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-				serviceIdDev2 = respCreateService.ServiceId
-			})
-
-			It("should be passed", func() {
-				By("create schemas when service schema id set is empty")
-				schemas := []*pb.Schema{
-					{
-						SchemaId: "first_schemaId",
-						Schema:   "first_schema",
-						Summary:  "first0summary",
-					},
-					{
-						SchemaId: "first_schemaId",
-						Schema:   "first_schema",
-						Summary:  "first0summary",
-					},
-				}
-				respCreateService, err := serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev1,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				respGetAllSchema, err := serviceResource.GetAllSchemaInfo(getContext(), &pb.GetAllSchemaRequest{
-					ServiceId: serviceIdDev1,
-				})
-				Expect(err).To(BeNil())
-				Expect(respGetAllSchema.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-				Expect(len(respGetAllSchema.Schemas)).To(Equal(1))
-
-				By("modify schemas when service schema id already exists")
-				schemas = []*pb.Schema{}
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev2,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("modify schemas")
-				schemas = []*pb.Schema{
-					{
-						SchemaId: "first_schemaId",
-						Schema:   "first_schema_change",
-						Summary:  "first0summary1change",
-					},
-				}
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev1,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				By("add schemas")
-				schemas = []*pb.Schema{
-					{
-						SchemaId: "second_schemaId",
-						Schema:   "second_schema",
-						Summary:  "second0summary",
-					},
-				}
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev1,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				service, err := disco.GetService(getContext(), &pb.GetServiceRequest{
-					ServiceId: serviceIdDev1,
-				})
-				Expect(err).To(BeNil())
-				Expect(service.Schemas).To(Equal([]string{"second_schemaId"}))
-
-				By("create empty")
-				schemas = []*pb.Schema{}
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev1,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("add new schemaId not exist in service schemaId")
-				schemas = []*pb.Schema{
-					{
-						SchemaId: "second_schemaId",
-						Schema:   "second_schema",
-						Summary:  "second0summary",
-					},
-				}
-				respCreateService, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdDev2,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				service, err = disco.GetService(getContext(), &pb.GetServiceRequest{
-					ServiceId: serviceIdDev2,
-				})
-				Expect(err).To(BeNil())
-				Expect(service.Schemas).To(Equal([]string{"second_schemaId"}))
-			})
-		})
-
-		Context("when modify schema and summary is empty", func() {
-			var (
-				serviceIdPro string
-			)
-
-			It("should be passed", func() {
-				respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-					Service: &pb.MicroService{
-						AppId:       "create_schemas_prod",
-						ServiceName: "create_schemas_service",
-						Version:     "1.0.1",
-						Level:       "FRONT",
-						Schemas: []string{
-							"first_schemaId",
-							"second_schemaId",
-						},
-						Status:      pb.MS_UP,
-						Environment: pb.ENV_PROD,
-					},
-				})
-				Expect(err).To(BeNil())
-				Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-				serviceIdPro = respCreateService.ServiceId
-			})
-
-			It("summary is empty", func() {
-				By("add schema when summary is empty")
-				respModifySchema, err := serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-					ServiceId: serviceIdPro,
-					SchemaId:  "first_schemaId",
-					Schema:    "first_schema",
-				})
-				Expect(err).To(BeNil())
-				Expect(respModifySchema.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				By("add schemas when summary in database is empty")
-				schemas := []*pb.Schema{
-					{
-						SchemaId: "first_schemaId",
-						Schema:   "first_schema",
-						Summary:  "first0summary",
-					},
-				}
-
-				respModifySchemas, err := serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdPro,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respModifySchemas.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				respExist, err := serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:      datasource.ExistTypeSchema,
-					ServiceId: serviceIdPro,
-					SchemaId:  "first_schemaId",
-				})
-
-				Expect(err).To(BeNil())
-				Expect(respExist.Summary).To(Equal("first0summary"))
-
-				schemas = []*pb.Schema{
-					{
-						SchemaId: "second_schemaId",
-						Schema:   "second_schema",
-						Summary:  "second0summary",
-					},
-				}
-				respModifySchemas, err = serviceResource.ModifySchemas(getContext(), &pb.ModifySchemasRequest{
-					ServiceId: serviceIdPro,
-					Schemas:   schemas,
-				})
-				Expect(err).To(BeNil())
-				Expect(respModifySchemas.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			})
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  "non-schema-content",
 		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
 	})
 
-	Describe("execute 'exist' operation", func() {
-		var (
-			serviceId string
-		)
-
-		It("should be passed", func() {
-			respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-				Service: &pb.MicroService{
-					AppId:       "query_schema_group",
-					ServiceName: "query_schema_service",
-					Version:     "1.0.0",
-					Level:       "FRONT",
-					Status:      pb.MS_UP,
-					Environment: pb.ENV_DEV,
-				},
-			})
-			Expect(err).To(BeNil())
-			Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			serviceId = respCreateService.ServiceId
-
-			resp, err := serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-				ServiceId: serviceId,
-				SchemaId:  "com.huawei.test",
-				Schema:    "query schema",
-				Summary:   "summary",
-			})
-			Expect(err).To(BeNil())
-			Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-			resp, err = serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-				ServiceId: serviceId,
-				SchemaId:  "com.huawei.test.no.summary",
-				Schema:    "query schema",
-			})
-			Expect(err).To(BeNil())
-			Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-		})
-
-		Context("when request is invalid", func() {
-			It("should be failed", func() {
-				By("service id is empty")
-				resp, err := serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:      "schema",
-					ServiceId: "",
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("schema id does not exist")
-				resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:      "schema",
-					ServiceId: serviceId,
-					SchemaId:  "noneschema",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("schema id is invalid")
-				resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:      "schema",
-					ServiceId: serviceId,
-					SchemaId:  TOO_LONG_SCHEMAID,
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-			})
-		})
-
-		Context("when request is valid", func() {
-			It("should be passed", func() {
-				resp, err := serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:      "schema",
-					ServiceId: serviceId,
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-				Expect(resp.Summary).To(Equal("summary"))
-
-				resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:        "schema",
-					ServiceId:   serviceId,
-					SchemaId:    "com.huawei.test",
-					AppId:       "()",
-					ServiceName: "",
-					Version:     "()",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				resp, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:      "schema",
-					ServiceId: serviceId,
-					SchemaId:  "com.huawei.test.no.summary",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-				Expect(resp.SchemaId).To(Equal("com.huawei.test.no.summary"))
-				Expect(resp.Summary).To(Equal(""))
-			})
+	t.Run("should be passed, when request is valid", func(t *testing.T) {
+		resp, err := disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  "com.huawei.test",
 		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, respPutData.Response.GetCode())
+		assert.Equal(t, "get schema", resp.Schema)
+		assert.Equal(t, "schema0summary", resp.SchemaSummary)
 	})
+}
+
+func TestDeleteSchema(t *testing.T) {
+	var (
+		serviceId string
+	)
+	respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			AppId:       "delete_schema_group",
+			ServiceName: "delete_schema_service",
+			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
+	defer serviceResource.Delete(getContext(), &pb.DeleteServiceRequest{ServiceId: serviceId, Force: true})
+
+	resp, err := disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
+		ServiceId: serviceId,
+		SchemaId:  "com.huawei.test",
+		Schema:    "delete schema",
+		Summary:   "summary",
+	})
+	assert.NoError(t, err)
+	assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
 
-	Describe("execute 'get' operation", func() {
-		var (
-			serviceId  string
-			serviceId1 string
-		)
-
-		var (
-			schemaId1     string = "all_schema1"
-			schemaId2     string = "all_schema2"
-			schemaId3     string = "all_schema3"
-			summary       string = "this0is1a2test"
-			schemaContent string = "the content is vary large"
-		)
-
-		It("should be passed", func() {
-			respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-				Service: &pb.MicroService{
-					AppId:       "get_schema_group",
-					ServiceName: "get_schema_service",
-					Version:     "1.0.0",
-					Level:       "FRONT",
-					Schemas: []string{
-						"non-schema-content",
-					},
-					Status:      pb.MS_UP,
-					Environment: pb.ENV_DEV,
-				},
-			})
-			Expect(err).To(BeNil())
-			Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			serviceId = respCreateService.ServiceId
-
-			resp, err := serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-				ServiceId: serviceId,
-				SchemaId:  "com.huawei.test",
-				Schema:    "get schema",
-				Summary:   "schema0summary",
-			})
-			Expect(err).To(BeNil())
-			Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-			respCreateService, err = serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-				Service: &pb.MicroService{
-					AppId:       "get_all_schema",
-					ServiceName: "get_all_schema",
-					Version:     "1.0.0",
-					Level:       "FRONT",
-					Schemas: []string{
-						schemaId1,
-						schemaId2,
-						schemaId3,
-					},
-					Status: pb.MS_UP,
-				},
-			})
-			Expect(err).To(BeNil())
-			Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			serviceId1 = respCreateService.ServiceId
-
-			respPutData, err := serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-				ServiceId: serviceId1,
-				SchemaId:  schemaId2,
-				Schema:    schemaContent,
-			})
-			Expect(err).To(BeNil())
-			Expect(respPutData.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-			respPutData, err = serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-				ServiceId: serviceId1,
-				SchemaId:  schemaId3,
-				Schema:    schemaContent,
-				Summary:   summary,
-			})
-			Expect(err).To(BeNil())
-			Expect(respPutData.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-			respGetAllSchema, err := serviceResource.GetAllSchemaInfo(getContext(), &pb.GetAllSchemaRequest{
-				ServiceId:  serviceId1,
-				WithSchema: false,
-			})
-			Expect(err).To(BeNil())
-			Expect(respGetAllSchema.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			schemas := respGetAllSchema.Schemas
-			for _, schema := range schemas {
-				if schema.SchemaId == schemaId1 {
-					Expect(schema.Summary).To(BeEmpty())
-					Expect(schema.Schema).To(BeEmpty())
-				}
-				if schema.SchemaId == schemaId2 {
-					Expect(schema.Summary).To(BeEmpty())
-					Expect(schema.Schema).To(BeEmpty())
-				}
-				if schema.SchemaId == schemaId3 {
-					Expect(schema.Summary).To(Equal(summary))
-					Expect(schema.Schema).To(BeEmpty())
-				}
-			}
+	t.Run("should be failed, when request is invalid", func(t *testing.T) {
+		_, err := disco.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  "noneschema",
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
 
-			respGetAllSchema, err = serviceResource.GetAllSchemaInfo(getContext(), &pb.GetAllSchemaRequest{
-				ServiceId:  serviceId1,
-				WithSchema: true,
-			})
-			Expect(err).To(BeNil())
-			Expect(respGetAllSchema.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			schemas = respGetAllSchema.Schemas
-			for _, schema := range schemas {
-				if schema.SchemaId == schemaId1 {
-					Expect(schema.Schema).To(BeEmpty())
-					Expect(schema.Schema).To(BeEmpty())
-				}
-				if schema.SchemaId == schemaId2 {
-					Expect(schema.Summary).To(BeEmpty())
-					Expect(schema.Schema).To(Equal(schemaContent))
-				}
-				if schema.SchemaId == schemaId3 {
-					Expect(schema.Summary).To(Equal(summary))
-					Expect(schema.Schema).To(Equal(schemaContent))
-				}
-			}
+		_, err = disco.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+			ServiceId: "",
+			SchemaId:  "com.huawei.test",
+		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
+		_, err = disco.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+			ServiceId: "noexistservice",
+			SchemaId:  "com.huawei.test",
 		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
 
-		Context("when request is invalid", func() {
-			It("should be failed", func() {
-				By("service does not exist")
-				resp, err := serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: "noneexistservice",
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrServiceNotExists))
-
-				respA, err := serviceResource.GetAllSchemaInfo(getContext(), &pb.GetAllSchemaRequest{
-					ServiceId: "noneexistservice",
-				})
-				Expect(err).To(BeNil())
-				Expect(respA.Response.GetCode()).To(Equal(pb.ErrServiceNotExists))
-
-				By("service id is empty")
-				resp, err = serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: "",
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				respA, err = serviceResource.GetAllSchemaInfo(getContext(), &pb.GetAllSchemaRequest{
-					ServiceId: "",
-				})
-				Expect(err).To(BeNil())
-				Expect(respA.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("service id is invalid")
-				resp, err = serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: TOO_LONG_SERVICEID,
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				respA, err = serviceResource.GetAllSchemaInfo(getContext(), &pb.GetAllSchemaRequest{
-					ServiceId: TOO_LONG_SERVICEID,
-				})
-				Expect(err).To(BeNil())
-				Expect(respA.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("schema id does not exist")
-				resp, err = serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  "nonexistschema",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrSchemaNotExists))
-
-				By("schema id is invalid")
-				resp, err = serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  "",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-				resp, err = serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  TOO_LONG_SCHEMAID,
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-				resp, err = serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  invalidSchemaId,
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
-
-				By("schema content does not exist")
-				resp, err = serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  "non-schema-content",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ErrSchemaNotExists))
-			})
-		})
-
-		Context("when request is valid", func() {
-			It("should be passed", func() {
-				resp, err := serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-				Expect(resp.Schema).To(Equal("get schema"))
-				Expect(resp.SchemaSummary).To(Equal("schema0summary"))
-			})
+		_, err = disco.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  invalidSchemaId,
 		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 	})
 
-	Describe("execute 'delete' operation", func() {
-		var (
-			serviceId string
-		)
-
-		It("should be passed", func() {
-			respCreateService, err := serviceResource.Create(getContext(), &pb.CreateServiceRequest{
-				Service: &pb.MicroService{
-					AppId:       "delete_schema_group",
-					ServiceName: "delete_schema_service",
-					Version:     "1.0.0",
-					Level:       "FRONT",
-					Status:      pb.MS_UP,
-				},
-			})
-			Expect(err).To(BeNil())
-			Expect(respCreateService.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-			serviceId = respCreateService.ServiceId
-
-			resp, err := serviceResource.ModifySchema(getContext(), &pb.ModifySchemaRequest{
-				ServiceId: serviceId,
-				SchemaId:  "com.huawei.test",
-				Schema:    "delete schema",
-				Summary:   "summary",
-			})
-			Expect(err).To(BeNil())
-			Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-		})
-
-		Context("when request is invalid", func() {
-			It("should be failed", func() {
-				By("schema id does not exist")
-				resp, err := serviceResource.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  "noneschema",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("service id is empty")
-				resp, err = serviceResource.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
-					ServiceId: "",
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("service id does not exist")
-				resp, err = serviceResource.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
-					ServiceId: "noexistservice",
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-
-				By("schema id is invalid")
-				resp, err = serviceResource.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  invalidSchemaId,
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).ToNot(Equal(pb.ResponseSuccess))
-			})
-		})
-
-		Context("when request is valid", func() {
-			It("should be passed", func() {
-				resp, err := serviceResource.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
-
-				respGet, err := serviceResource.GetSchemaInfo(getContext(), &pb.GetSchemaRequest{
-					ServiceId: serviceId,
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(respGet.Response.GetCode()).To(Equal(pb.ErrSchemaNotExists))
-
-				respExist, err := serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
-					Type:      "schema",
-					ServiceId: serviceId,
-					SchemaId:  "com.huawei.test",
-				})
-				Expect(err).To(BeNil())
-				Expect(respExist.Response.GetCode()).To(Equal(pb.ErrSchemaNotExists))
-			})
+	t.Run("should be passed, when request is valid", func(t *testing.T) {
+		resp, err := disco.DeleteSchema(getContext(), &pb.DeleteSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  "com.huawei.test",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+
+		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
+			ServiceId: serviceId,
+			SchemaId:  "com.huawei.test",
+		})
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
+
+		_, err = serviceResource.Exist(getContext(), &pb.GetExistenceRequest{
+			Type:      "schema",
+			ServiceId: serviceId,
+			SchemaId:  "com.huawei.test",
 		})
+		testErr = err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrSchemaNotExists, testErr.Code)
 	})
-})
+}
diff --git a/server/service/disco/service_suite_test.go b/server/service/disco/service_suite_test.go
index 2dd1d95..bacf736 100644
--- a/server/service/disco/service_suite_test.go
+++ b/server/service/disco/service_suite_test.go
@@ -33,9 +33,9 @@ import (
 
 var serviceResource proto.ServiceCtrlServer
 
-var _ = BeforeSuite(func() {
+func init() {
 	serviceResource = disco.AssembleResources()
-})
+}
 
 func getContext() context.Context {
 	return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
diff --git a/server/service/govern/view_test.go b/server/service/govern/view_test.go
index f2f4958..4d844f9 100644
--- a/server/service/govern/view_test.go
+++ b/server/service/govern/view_test.go
@@ -125,7 +125,7 @@ var _ = Describe("'Govern' service", func() {
 			Expect(resp.Response.GetCode()).To(Equal(pb.ResponseSuccess))
 			serviceId = resp.ServiceId
 
-			core.ServiceAPI.ModifySchema(getContext(), &pb.ModifySchemaRequest{
+			disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
 				ServiceId: serviceId,
 				SchemaId:  "schemaId",
 				Schema:    "detail",