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

[servicecomb-service-center] branch quota created (now 7af9893)

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

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


      at 7af9893  Feature: add resource usage service

This branch includes the following new commits:

     new 7af9893  Feature: add resource usage service

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[servicecomb-service-center] 01/01: Feature: add resource usage service

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7af98936f9b29c86683d69b80feee1b39be996f3
Author: little-cui <su...@qq.com>
AuthorDate: Tue Jan 11 14:23:18 2022 +0800

    Feature: add resource usage service
---
 server/plugin/quota/buildin/account.go       | 32 -----------
 server/plugin/quota/buildin/buildin.go       | 12 ++--
 server/plugin/quota/buildin/instance.go      | 33 -----------
 server/plugin/quota/buildin/instance_test.go | 66 ----------------------
 server/plugin/quota/buildin/role.go          | 32 -----------
 server/plugin/quota/buildin/schema.go        | 36 ------------
 server/plugin/quota/buildin/schema_test.go   | 71 ------------------------
 server/plugin/quota/buildin/service.go       | 33 -----------
 server/plugin/quota/buildin/service_test.go  | 60 --------------------
 server/service/disco/instance.go             |  8 +++
 server/service/disco/instance_test.go        | 61 +++++++++++++++-----
 server/service/disco/metadata.go             |  8 +++
 server/service/disco/metadata_test.go        | 83 +++++++++++++++++++---------
 server/service/disco/schema.go               | 11 ++++
 server/service/disco/schema_test.go          | 55 +++++++++++++++---
 server/service/disco/tag_test.go             |  2 +-
 server/service/quota/service_test.go         |  3 +-
 server/service/rbac/account_service.go       |  8 +++
 server/service/rbac/role_service.go          |  8 +++
 19 files changed, 205 insertions(+), 417 deletions(-)

diff --git a/server/plugin/quota/buildin/account.go b/server/plugin/quota/buildin/account.go
deleted file mode 100644
index a5ec0af..0000000
--- a/server/plugin/quota/buildin/account.go
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 buildin
-
-import (
-	"context"
-
-	"github.com/apache/servicecomb-service-center/datasource/rbac"
-)
-
-func AccountUsage(ctx context.Context) (int64, error) {
-	_, used, err := rbac.Instance().ListAccount(ctx)
-	if err != nil {
-		return 0, err
-	}
-	return used, nil
-}
diff --git a/server/plugin/quota/buildin/buildin.go b/server/plugin/quota/buildin/buildin.go
index 5068687..aab18cf 100644
--- a/server/plugin/quota/buildin/buildin.go
+++ b/server/plugin/quota/buildin/buildin.go
@@ -26,7 +26,9 @@ import (
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/config"
 	"github.com/apache/servicecomb-service-center/server/plugin/quota"
+	"github.com/apache/servicecomb-service-center/server/service/disco"
 	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+	"github.com/apache/servicecomb-service-center/server/service/rbac"
 	pb "github.com/go-chassis/cari/discovery"
 )
 
@@ -99,24 +101,24 @@ func (q *Quota) RemandQuotas(ctx context.Context, resourceType quota.ResourceTyp
 func (q *Quota) Usage(ctx context.Context, req *quota.Request) (int64, error) {
 	switch req.QuotaType {
 	case quotasvc.TypeInstance:
-		return InstanceUsage(ctx, &pb.GetServiceCountRequest{
+		return disco.InstanceUsage(ctx, &pb.GetServiceCountRequest{
 			Domain:  util.ParseDomain(ctx),
 			Project: util.ParseProject(ctx),
 		})
 	case quotasvc.TypeService:
-		return ServiceUsage(ctx, &pb.GetServiceCountRequest{
+		return disco.ServiceUsage(ctx, &pb.GetServiceCountRequest{
 			Domain:  util.ParseDomain(ctx),
 			Project: util.ParseProject(ctx),
 		})
 	case quotasvc.TypeSchema:
-		return SchemaUsage(ctx, req.ServiceID)
+		return disco.Usage(ctx, req.ServiceID)
 	case quotasvc.TypeTag:
 		// always re-create the service old tags
 		return 0, nil
 	case quotasvc.TypeAccount:
-		return AccountUsage(ctx)
+		return rbac.AccountUsage(ctx)
 	case quotasvc.TypeRole:
-		return RoleUsage(ctx)
+		return rbac.RoleUsage(ctx)
 	default:
 		return 0, nil
 	}
diff --git a/server/plugin/quota/buildin/instance.go b/server/plugin/quota/buildin/instance.go
deleted file mode 100644
index 5b485ba..0000000
--- a/server/plugin/quota/buildin/instance.go
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 buildin
-
-import (
-	"context"
-
-	"github.com/apache/servicecomb-service-center/datasource"
-	pb "github.com/go-chassis/cari/discovery"
-)
-
-func InstanceUsage(ctx context.Context, request *pb.GetServiceCountRequest) (int64, error) {
-	resp, err := datasource.GetMetadataManager().CountInstance(ctx, request)
-	if err != nil {
-		return 0, err
-	}
-	return resp.Count, nil
-}
diff --git a/server/plugin/quota/buildin/instance_test.go b/server/plugin/quota/buildin/instance_test.go
deleted file mode 100644
index 6352c59..0000000
--- a/server/plugin/quota/buildin/instance_test.go
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 buildin_test
-
-import (
-	"context"
-	"testing"
-
-	_ "github.com/apache/servicecomb-service-center/test"
-
-	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota/buildin"
-	"github.com/apache/servicecomb-service-center/server/service/disco"
-	pb "github.com/go-chassis/cari/discovery"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestInstanceUsage(t *testing.T) {
-	t.Run("get domain/project without instance usage, should return 0", func(t *testing.T) {
-		usage, err := buildin.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
-			Domain:  "domain_without_service",
-			Project: "project_without_service",
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, int64(0), usage)
-	})
-
-	t.Run("get domain/project with 1 instance usage, should return 1", func(t *testing.T) {
-		ctx := util.SetDomainProject(context.Background(), "domain_with_service", "project_with_service")
-		resp, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
-			Service: &pb.MicroService{
-				ServiceName: "test",
-			},
-		})
-		assert.NoError(t, err)
-		defer disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
-
-		_, err = disco.RegisterInstance(ctx, &pb.RegisterInstanceRequest{Instance: &pb.MicroServiceInstance{
-			ServiceId: resp.ServiceId,
-			HostName:  "test",
-		}})
-		assert.NoError(t, err)
-
-		usage, err := buildin.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
-			Domain:  "domain_with_service",
-			Project: "project_with_service",
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, int64(1), usage)
-	})
-}
diff --git a/server/plugin/quota/buildin/role.go b/server/plugin/quota/buildin/role.go
deleted file mode 100644
index c7cb44f..0000000
--- a/server/plugin/quota/buildin/role.go
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 buildin
-
-import (
-	"context"
-
-	"github.com/apache/servicecomb-service-center/datasource/rbac"
-)
-
-func RoleUsage(ctx context.Context) (int64, error) {
-	_, used, err := rbac.Instance().ListRole(ctx)
-	if err != nil {
-		return 0, err
-	}
-	return used, nil
-}
diff --git a/server/plugin/quota/buildin/schema.go b/server/plugin/quota/buildin/schema.go
deleted file mode 100644
index 418c316..0000000
--- a/server/plugin/quota/buildin/schema.go
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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 buildin
-
-import (
-	"context"
-
-	discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
-	"github.com/go-chassis/cari/discovery"
-)
-
-func SchemaUsage(ctx context.Context, serviceID string) (int64, error) {
-	schemas, err := discosvc.ListSchema(ctx, &discovery.GetAllSchemaRequest{
-		ServiceId:  serviceID,
-		WithSchema: false,
-	})
-	if err != nil {
-		return 0, err
-	}
-	return int64(len(schemas)), nil
-}
diff --git a/server/plugin/quota/buildin/schema_test.go b/server/plugin/quota/buildin/schema_test.go
deleted file mode 100644
index b1dba0a..0000000
--- a/server/plugin/quota/buildin/schema_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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 buildin_test
-
-import (
-	"context"
-	"testing"
-
-	_ "github.com/apache/servicecomb-service-center/test"
-	"github.com/go-chassis/cari/pkg/errsvc"
-
-	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota/buildin"
-	"github.com/apache/servicecomb-service-center/server/service/disco"
-	pb "github.com/go-chassis/cari/discovery"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestSchemaUsage(t *testing.T) {
-	ctx := util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
-
-	resp, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
-		Service: &pb.MicroService{
-			ServiceName: "TestSchemaUsage",
-		},
-	})
-	assert.NoError(t, err)
-	serviceID := resp.ServiceId
-	defer disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceID, Force: true})
-
-	t.Run("get not exist service schema usage, should failed", func(t *testing.T) {
-		_, err := buildin.SchemaUsage(ctx, "note_exist_service_id")
-		testErr := err.(*errsvc.Error)
-		assert.Error(t, testErr)
-		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
-	})
-
-	t.Run("get usage without schemas, should return 0", func(t *testing.T) {
-		usage, err := buildin.SchemaUsage(ctx, serviceID)
-		assert.NoError(t, err)
-		assert.Equal(t, int64(0), usage)
-	})
-
-	t.Run("get usage with schemas, should return 1", func(t *testing.T) {
-		err := disco.PutSchema(ctx, &pb.ModifySchemaRequest{
-			ServiceId: serviceID,
-			SchemaId:  "schemaID_1",
-			Schema:    "schema_1",
-		})
-		assert.NoError(t, err)
-
-		usage, err := buildin.SchemaUsage(ctx, serviceID)
-		assert.NoError(t, err)
-		assert.Equal(t, int64(1), usage)
-	})
-}
diff --git a/server/plugin/quota/buildin/service.go b/server/plugin/quota/buildin/service.go
deleted file mode 100644
index a243889..0000000
--- a/server/plugin/quota/buildin/service.go
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 buildin
-
-import (
-	"context"
-
-	"github.com/apache/servicecomb-service-center/datasource"
-	pb "github.com/go-chassis/cari/discovery"
-)
-
-func ServiceUsage(ctx context.Context, request *pb.GetServiceCountRequest) (int64, error) {
-	resp, err := datasource.GetMetadataManager().CountService(ctx, request)
-	if err != nil {
-		return 0, err
-	}
-	return resp.Count, nil
-}
diff --git a/server/plugin/quota/buildin/service_test.go b/server/plugin/quota/buildin/service_test.go
deleted file mode 100644
index 11ffa66..0000000
--- a/server/plugin/quota/buildin/service_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 buildin_test
-
-import (
-	"context"
-	"testing"
-
-	_ "github.com/apache/servicecomb-service-center/test"
-
-	"github.com/apache/servicecomb-service-center/pkg/util"
-	"github.com/apache/servicecomb-service-center/server/plugin/quota/buildin"
-	"github.com/apache/servicecomb-service-center/server/service/disco"
-	pb "github.com/go-chassis/cari/discovery"
-	"github.com/stretchr/testify/assert"
-)
-
-func TestServiceUsage(t *testing.T) {
-	t.Run("get domain/project without service usage, should return 0", func(t *testing.T) {
-		usage, err := buildin.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
-			Domain:  "domain_without_service",
-			Project: "project_without_service",
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, int64(0), usage)
-	})
-
-	t.Run("get domain/project with 1 service usage, should return 1", func(t *testing.T) {
-		ctx := util.SetDomainProject(context.Background(), "domain_with_service", "project_with_service")
-		resp, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
-			Service: &pb.MicroService{
-				ServiceName: "test",
-			},
-		})
-		assert.NoError(t, err)
-		defer disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
-
-		usage, err := buildin.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
-			Domain:  "domain_with_service",
-			Project: "project_with_service",
-		})
-		assert.NoError(t, err)
-		assert.Equal(t, int64(1), usage)
-	})
-}
diff --git a/server/service/disco/instance.go b/server/service/disco/instance.go
index 95689b8..b2fa07d 100644
--- a/server/service/disco/instance.go
+++ b/server/service/disco/instance.go
@@ -377,3 +377,11 @@ func checkInstanceQuota(ctx context.Context) error {
 	}
 	return nil
 }
+
+func InstanceUsage(ctx context.Context, request *pb.GetServiceCountRequest) (int64, error) {
+	resp, err := datasource.GetMetadataManager().CountInstance(ctx, request)
+	if err != nil {
+		return 0, err
+	}
+	return resp.Count, nil
+}
diff --git a/server/service/disco/instance_test.go b/server/service/disco/instance_test.go
index ad89a02..0c22de1 100644
--- a/server/service/disco/instance_test.go
+++ b/server/service/disco/instance_test.go
@@ -121,9 +121,9 @@ func TestRegisterInstance(t *testing.T) {
 					Url:      TOO_LONG_URL[:len(TOO_LONG_URL)-1],
 				},
 				DataCenterInfo: &pb.DataCenterInfo{
-					Name:          TOO_LONG_SERVICENAME[:len(TOO_LONG_SERVICENAME)-1],
-					Region:        TOO_LONG_SERVICENAME[:len(TOO_LONG_SERVICENAME)-1],
-					AvailableZone: TOO_LONG_SERVICENAME[:len(TOO_LONG_SERVICENAME)-1],
+					Name:          TooLongServiceName[:len(TooLongServiceName)-1],
+					Region:        TooLongServiceName[:len(TooLongServiceName)-1],
+					AvailableZone: TooLongServiceName[:len(TooLongServiceName)-1],
 				},
 			},
 		})
@@ -674,7 +674,7 @@ func TestFindManyInstances(t *testing.T) {
 			Services: []*pb.FindService{
 				{
 					Service: &pb.MicroServiceKey{
-						AppId:       TOO_LONG_APPID,
+						AppId:       TooLongAppID,
 						ServiceName: "query_instance_service",
 					},
 				},
@@ -720,7 +720,7 @@ func TestFindManyInstances(t *testing.T) {
 				{
 					Service: &pb.MicroServiceKey{
 						AppId:       "query_instance",
-						ServiceName: TOO_LONG_EXISTENCE,
+						ServiceName: TooLongExistence,
 					},
 				},
 			},
@@ -1345,7 +1345,7 @@ func TestFindInstances(t *testing.T) {
 	t.Run("when query invalid parameters, should be failed", func(t *testing.T) {
 		_, err := discosvc.FindInstances(ctx, &pb.FindInstancesRequest{
 			ConsumerServiceId: serviceId1,
-			AppId:             TOO_LONG_APPID,
+			AppId:             TooLongAppID,
 			ServiceName:       "query_instance_service",
 		})
 		testErr := err.(*errsvc.Error)
@@ -1373,7 +1373,7 @@ func TestFindInstances(t *testing.T) {
 		_, err = discosvc.FindInstances(ctx, &pb.FindInstancesRequest{
 			ConsumerServiceId: serviceId1,
 			AppId:             "query_instance",
-			ServiceName:       TOO_LONG_EXISTENCE,
+			ServiceName:       TooLongExistence,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -1740,7 +1740,7 @@ func TestUnregisterInstance(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		err = discosvc.UnregisterInstance(ctx, &pb.UnregisterInstanceRequest{
-			ServiceId:  TOO_LONG_SERVICEID,
+			ServiceId:  TooLongServiceID,
 			InstanceId: instanceId,
 		})
 		testErr = err.(*errsvc.Error)
@@ -1773,7 +1773,7 @@ func TestUnregisterInstance(t *testing.T) {
 
 		err = discosvc.UnregisterInstance(ctx, &pb.UnregisterInstanceRequest{
 			ServiceId:  serviceId,
-			InstanceId: TOO_LONG_SERVICEID,
+			InstanceId: TooLongServiceID,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -1855,7 +1855,7 @@ func TestSendHeartbeat(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		err = discosvc.SendHeartbeat(ctx, &pb.HeartbeatRequest{
-			ServiceId:  TOO_LONG_SERVICEID,
+			ServiceId:  TooLongServiceID,
 			InstanceId: instanceId1,
 		})
 		testErr = err.(*errsvc.Error)
@@ -1880,7 +1880,7 @@ func TestSendHeartbeat(t *testing.T) {
 
 		err = discosvc.SendHeartbeat(ctx, &pb.HeartbeatRequest{
 			ServiceId:  serviceId,
-			InstanceId: TOO_LONG_SERVICEID,
+			InstanceId: TooLongServiceID,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -2132,7 +2132,7 @@ func TestUpdateInstance(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		err = discosvc.PutInstanceProperties(ctx, &pb.UpdateInstancePropsRequest{
-			ServiceId:  TOO_LONG_SERVICEID,
+			ServiceId:  TooLongServiceID,
 			InstanceId: instanceId,
 			Properties: map[string]string{
 				"test": "test",
@@ -2166,7 +2166,7 @@ func TestUpdateInstance(t *testing.T) {
 
 		err = discosvc.PutInstanceProperties(ctx, &pb.UpdateInstancePropsRequest{
 			ServiceId:  serviceId,
-			InstanceId: TOO_LONG_SERVICEID,
+			InstanceId: TooLongServiceID,
 			Properties: map[string]string{
 				"test": "test",
 			},
@@ -2204,3 +2204,38 @@ func assertInstanceContain(t *testing.T, instances []*pb.MicroServiceInstance, i
 	}
 	assert.True(t, found)
 }
+
+func TestInstanceUsage(t *testing.T) {
+	t.Run("get domain/project without instance usage, should return 0", func(t *testing.T) {
+		usage, err := discosvc.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
+			Domain:  "domain_without_service",
+			Project: "project_without_service",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, int64(0), usage)
+	})
+
+	t.Run("get domain/project with 1 instance usage, should return 1", func(t *testing.T) {
+		ctx := util.SetDomainProject(context.Background(), "domain_with_service", "project_with_service")
+		resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceName: "test",
+			},
+		})
+		assert.NoError(t, err)
+		defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+		_, err = discosvc.RegisterInstance(ctx, &pb.RegisterInstanceRequest{Instance: &pb.MicroServiceInstance{
+			ServiceId: resp.ServiceId,
+			HostName:  "test",
+		}})
+		assert.NoError(t, err)
+
+		usage, err := discosvc.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
+			Domain:  "domain_with_service",
+			Project: "project_with_service",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, int64(1), usage)
+	})
+}
diff --git a/server/service/disco/metadata.go b/server/service/disco/metadata.go
index 04455dd..87b801b 100644
--- a/server/service/disco/metadata.go
+++ b/server/service/disco/metadata.go
@@ -243,3 +243,11 @@ func PutServiceProperties(ctx context.Context, request *pb.UpdateServicePropsReq
 
 	return datasource.GetMetadataManager().PutServiceProperties(ctx, request)
 }
+
+func ServiceUsage(ctx context.Context, request *pb.GetServiceCountRequest) (int64, error) {
+	resp, err := datasource.GetMetadataManager().CountService(ctx, request)
+	if err != nil {
+		return 0, err
+	}
+	return resp.Count, nil
+}
diff --git a/server/service/disco/metadata_test.go b/server/service/disco/metadata_test.go
index 40c1fcd..3519dd7 100644
--- a/server/service/disco/metadata_test.go
+++ b/server/service/disco/metadata_test.go
@@ -18,10 +18,12 @@
 package disco_test
 
 import (
+	"context"
 	"strconv"
 	"strings"
 	"testing"
 
+	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/core"
 	"github.com/apache/servicecomb-service-center/server/service/disco"
 	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
@@ -31,14 +33,14 @@ import (
 )
 
 var (
-	TOO_LONG_APPID       = strings.Repeat("x", 161)
-	TOO_LONG_SCHEMAID    = strings.Repeat("x", 161)
-	TOO_LONG_SERVICEID   = strings.Repeat("x", 65)
-	TOO_LONG_SERVICENAME = strings.Repeat("x", 129)
-	TOO_LONG_EXISTENCE   = strings.Repeat("x", 128+160+2)
-	TOO_LONG_ALIAS       = strings.Repeat("x", 129)
-	TOO_LONG_FRAMEWORK   = strings.Repeat("x", 65)
-	TOO_LONG_DESCRIPTION = strings.Repeat("x", 257)
+	TooLongAppID       = strings.Repeat("x", 161)
+	TooLongSchemaID    = strings.Repeat("x", 161)
+	TooLongServiceID   = strings.Repeat("x", 65)
+	TooLongServiceName = strings.Repeat("x", 129)
+	TooLongExistence   = strings.Repeat("x", 128+160+2)
+	TooLongAlias       = strings.Repeat("x", 129)
+	TooLongFramework   = strings.Repeat("x", 65)
+	TooLongDescription = strings.Repeat("x", 257)
 )
 
 func TestRegisterService(t *testing.T) {
@@ -64,18 +66,18 @@ func TestRegisterService(t *testing.T) {
 		}
 		r := &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
-				AppId:       TOO_LONG_APPID[:len(TOO_LONG_APPID)-1],
-				ServiceName: TOO_LONG_SERVICENAME[:len(TOO_LONG_SERVICENAME)-1],
+				AppId:       TooLongAppID[:len(TooLongAppID)-1],
+				ServiceName: TooLongServiceName[:len(TooLongServiceName)-1],
 				Version:     "32767.32767.32767.32767",
-				Alias:       TOO_LONG_ALIAS[:len(TOO_LONG_ALIAS)-1],
+				Alias:       TooLongAlias[:len(TooLongAlias)-1],
 				Level:       "BACK",
 				Status:      "UP",
-				Schemas:     []string{TOO_LONG_SCHEMAID[:len(TOO_LONG_SCHEMAID)-1]},
+				Schemas:     []string{TooLongSchemaID[:len(TooLongSchemaID)-1]},
 				Paths:       paths,
 				Properties:  properties,
 				Framework: &pb.FrameWork{
-					Name:    TOO_LONG_FRAMEWORK[:len(TOO_LONG_FRAMEWORK)-1],
-					Version: TOO_LONG_FRAMEWORK[:len(TOO_LONG_FRAMEWORK)-1],
+					Name:    TooLongFramework[:len(TooLongFramework)-1],
+					Version: TooLongFramework[:len(TooLongFramework)-1],
 				},
 				RegisterBy: "SDK",
 			},
@@ -440,7 +442,7 @@ func TestRegisterService(t *testing.T) {
 
 		r = &pb.CreateServiceRequest{
 			Service: &pb.MicroService{
-				AppId:       TOO_LONG_APPID,
+				AppId:       TooLongAppID,
 				ServiceName: "service-validate",
 				Version:     "1.0.0",
 				Level:       "BACK",
@@ -569,7 +571,7 @@ func TestRegisterService(t *testing.T) {
 			Service: &pb.MicroService{
 				AppId:       "default",
 				ServiceName: "service-validate-alias",
-				Alias:       TOO_LONG_ALIAS,
+				Alias:       TooLongAlias,
 				Version:     "1.0.0",
 				Level:       "BACK",
 				Status:      "UP",
@@ -587,7 +589,7 @@ func TestRegisterService(t *testing.T) {
 				Version:     "1.0.4",
 				Level:       "BACK",
 				Framework: &pb.FrameWork{
-					Version: TOO_LONG_FRAMEWORK,
+					Version: TooLongFramework,
 				},
 				Properties: make(map[string]string),
 				Status:     "UP",
@@ -605,7 +607,7 @@ func TestRegisterService(t *testing.T) {
 				Version:     "1.0.5",
 				Level:       "BACK",
 				Framework: &pb.FrameWork{
-					Name: TOO_LONG_FRAMEWORK,
+					Name: TooLongFramework,
 				},
 				Properties: make(map[string]string),
 				Status:     "UP",
@@ -656,7 +658,7 @@ func TestRegisterService(t *testing.T) {
 				Version:     "1.0.6",
 				Level:       "BACK",
 				Status:      "UP",
-				Description: TOO_LONG_DESCRIPTION,
+				Description: TooLongDescription,
 			},
 		}
 		_, err = disco.RegisterService(ctx, r)
@@ -670,7 +672,7 @@ func TestRegisterService(t *testing.T) {
 				ServiceName: "schema-test",
 				Level:       "BACK",
 				Status:      "UP",
-				Schemas:     []string{TOO_LONG_SCHEMAID},
+				Schemas:     []string{TooLongSchemaID},
 			},
 		}
 		_, err = disco.RegisterService(ctx, r)
@@ -806,7 +808,7 @@ func TestUnregisterService(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		err = disco.UnregisterService(ctx, &pb.DeleteServiceRequest{
-			ServiceId: TOO_LONG_SERVICEID,
+			ServiceId: TooLongServiceID,
 			Force:     true,
 		})
 		testErr = err.(*errsvc.Error)
@@ -939,7 +941,7 @@ func TestUnregisterManyService(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		_, err = disco.UnregisterManyService(getContext(), &pb.DelServicesRequest{
-			ServiceIds: []string{TOO_LONG_SERVICEID},
+			ServiceIds: []string{TooLongServiceID},
 			Force:      false,
 		})
 		testErr = err.(*errsvc.Error)
@@ -1056,7 +1058,7 @@ func TestExistService(t *testing.T) {
 	t.Run("when param is invalid, should be failed", func(t *testing.T) {
 		_, err := disco.ExistService(ctx, &pb.GetExistenceRequest{
 			Type:        "microservice",
-			ServiceName: TOO_LONG_EXISTENCE,
+			ServiceName: TooLongExistence,
 			Version:     "1.0.0",
 			AppId:       "exist_appId",
 		})
@@ -1076,7 +1078,7 @@ func TestExistService(t *testing.T) {
 
 		_, err = disco.ExistService(ctx, &pb.GetExistenceRequest{
 			Type:        "microservice",
-			AppId:       TOO_LONG_APPID,
+			AppId:       TooLongAppID,
 			ServiceName: "exist-invalid-appid",
 			Version:     "3.0.0",
 		})
@@ -1316,7 +1318,7 @@ func TestUpdateService(t *testing.T) {
 
 	t.Run("when request is invalid, should be failed", func(t *testing.T) {
 		r := &pb.UpdateServicePropsRequest{
-			ServiceId:  TOO_LONG_SERVICEID,
+			ServiceId:  TooLongServiceID,
 			Properties: map[string]string{},
 		}
 		err := disco.PutServiceProperties(ctx, r)
@@ -1351,7 +1353,7 @@ func TestListService(t *testing.T) {
 		assert.Nil(t, service)
 
 		service, err = disco.GetService(getContext(), &pb.GetServiceRequest{
-			ServiceId: TOO_LONG_SERVICEID,
+			ServiceId: TooLongServiceID,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -1359,3 +1361,32 @@ func TestListService(t *testing.T) {
 		assert.Nil(t, service)
 	})
 }
+
+func TestServiceUsage(t *testing.T) {
+	t.Run("get domain/project without service usage, should return 0", func(t *testing.T) {
+		usage, err := disco.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
+			Domain:  "domain_without_service",
+			Project: "project_without_service",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, int64(0), usage)
+	})
+
+	t.Run("get domain/project with 1 service usage, should return 1", func(t *testing.T) {
+		ctx := util.SetDomainProject(context.Background(), "domain_with_service", "project_with_service")
+		resp, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
+			Service: &pb.MicroService{
+				ServiceName: "test",
+			},
+		})
+		assert.NoError(t, err)
+		defer disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+		usage, err := disco.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
+			Domain:  "domain_with_service",
+			Project: "project_with_service",
+		})
+		assert.NoError(t, err)
+		assert.Equal(t, int64(1), usage)
+	})
+}
diff --git a/server/service/disco/schema.go b/server/service/disco/schema.go
index a84087c..5c59015 100644
--- a/server/service/disco/schema.go
+++ b/server/service/disco/schema.go
@@ -358,3 +358,14 @@ func checkSchemaQuota(ctx context.Context, serviceID string, schemaID string) er
 	}
 	return nil
 }
+
+func Usage(ctx context.Context, serviceID string) (int64, error) {
+	schemas, err := ListSchema(ctx, &pb.GetAllSchemaRequest{
+		ServiceId:  serviceID,
+		WithSchema: false,
+	})
+	if err != nil {
+		return 0, err
+	}
+	return int64(len(schemas)), nil
+}
diff --git a/server/service/disco/schema_test.go b/server/service/disco/schema_test.go
index 3c75867..c77f9b0 100644
--- a/server/service/disco/schema_test.go
+++ b/server/service/disco/schema_test.go
@@ -17,12 +17,14 @@
 package disco_test
 
 import (
+	"context"
 	"strconv"
 	"strings"
 	"testing"
 
 	"github.com/apache/servicecomb-service-center/datasource"
 	"github.com/apache/servicecomb-service-center/datasource/schema"
+	"github.com/apache/servicecomb-service-center/pkg/util"
 	"github.com/apache/servicecomb-service-center/server/service/disco"
 	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
 	pb "github.com/go-chassis/cari/discovery"
@@ -35,7 +37,7 @@ const (
 )
 
 var (
-	TOO_LONG_SUMMARY = strings.Repeat("x", 129)
+	TooLongSummary = strings.Repeat("x", 129)
 )
 
 func TestPutSchema(t *testing.T) {
@@ -132,7 +134,7 @@ func TestPutSchema(t *testing.T) {
 			ServiceId: serviceIdDev,
 			SchemaId:  "com.huawei.test",
 			Schema:    "create schema",
-			Summary:   TOO_LONG_SUMMARY,
+			Summary:   TooLongSummary,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -228,7 +230,7 @@ func TestPutSchema(t *testing.T) {
 				{
 					SchemaId: "com.huawei.test",
 					Schema:   "create schema",
-					Summary:  TOO_LONG_SUMMARY,
+					Summary:  TooLongSummary,
 				},
 			},
 		})
@@ -539,7 +541,7 @@ func TestExistSchema(t *testing.T) {
 
 		_, err = disco.ExistSchema(getContext(), &pb.GetSchemaRequest{
 			ServiceId: serviceId,
-			SchemaId:  TOO_LONG_SCHEMAID,
+			SchemaId:  TooLongSchemaID,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -708,7 +710,7 @@ func TestGetSchema(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
-			ServiceId: TOO_LONG_SERVICEID,
+			ServiceId: TooLongServiceID,
 			SchemaId:  "com.huawei.test",
 		})
 		testErr = err.(*errsvc.Error)
@@ -716,7 +718,7 @@ func TestGetSchema(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		_, err = disco.ListSchema(getContext(), &pb.GetAllSchemaRequest{
-			ServiceId: TOO_LONG_SERVICEID,
+			ServiceId: TooLongServiceID,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -740,7 +742,7 @@ func TestGetSchema(t *testing.T) {
 
 		_, err = disco.GetSchema(getContext(), &pb.GetSchemaRequest{
 			ServiceId: serviceId,
-			SchemaId:  TOO_LONG_SCHEMAID,
+			SchemaId:  TooLongSchemaID,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
@@ -1088,3 +1090,42 @@ func findSchemaBySchemaID(schemas []*pb.Schema, schemaID string) *pb.Schema {
 	}
 	return nil
 }
+
+func TestSchemaUsage(t *testing.T) {
+	ctx := util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
+
+	resp, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
+		Service: &pb.MicroService{
+			ServiceName: "TestSchemaUsage",
+		},
+	})
+	assert.NoError(t, err)
+	serviceID := resp.ServiceId
+	defer disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: serviceID, Force: true})
+
+	t.Run("get not exist service schema usage, should failed", func(t *testing.T) {
+		_, err := disco.Usage(ctx, "note_exist_service_id")
+		testErr := err.(*errsvc.Error)
+		assert.Error(t, testErr)
+		assert.Equal(t, pb.ErrServiceNotExists, testErr.Code)
+	})
+
+	t.Run("get usage without schemas, should return 0", func(t *testing.T) {
+		usage, err := disco.Usage(ctx, serviceID)
+		assert.NoError(t, err)
+		assert.Equal(t, int64(0), usage)
+	})
+
+	t.Run("get usage with schemas, should return 1", func(t *testing.T) {
+		err := disco.PutSchema(ctx, &pb.ModifySchemaRequest{
+			ServiceId: serviceID,
+			SchemaId:  "schemaID_1",
+			Schema:    "schema_1",
+		})
+		assert.NoError(t, err)
+
+		usage, err := disco.Usage(ctx, serviceID)
+		assert.NoError(t, err)
+		assert.Equal(t, int64(1), usage)
+	})
+}
diff --git a/server/service/disco/tag_test.go b/server/service/disco/tag_test.go
index 6a87fa7..e370765 100644
--- a/server/service/disco/tag_test.go
+++ b/server/service/disco/tag_test.go
@@ -198,7 +198,7 @@ func TestListTag(t *testing.T) {
 		assert.Equal(t, pb.ErrInvalidParams, testErr.Code)
 
 		_, err = disco.ListTag(ctx, &pb.GetServiceTagsRequest{
-			ServiceId: TOO_LONG_SERVICEID,
+			ServiceId: TooLongServiceID,
 		})
 		testErr = err.(*errsvc.Error)
 		assert.Error(t, testErr)
diff --git a/server/service/quota/service_test.go b/server/service/quota/service_test.go
index 2a3884b..664cadd 100644
--- a/server/service/quota/service_test.go
+++ b/server/service/quota/service_test.go
@@ -21,10 +21,9 @@ import (
 	"context"
 	"testing"
 
-	_ "github.com/apache/servicecomb-service-center/test"
-
 	"github.com/apache/servicecomb-service-center/pkg/util"
 	quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+	_ "github.com/apache/servicecomb-service-center/test"
 	"github.com/stretchr/testify/assert"
 )
 
diff --git a/server/service/rbac/account_service.go b/server/service/rbac/account_service.go
index 04d0fa4..0b4297d 100644
--- a/server/service/rbac/account_service.go
+++ b/server/service/rbac/account_service.go
@@ -181,3 +181,11 @@ func illegalAccountCheck(ctx context.Context, target string) error {
 	}
 	return nil
 }
+
+func AccountUsage(ctx context.Context) (int64, error) {
+	_, used, err := rbac.Instance().ListAccount(ctx)
+	if err != nil {
+		return 0, err
+	}
+	return used, nil
+}
diff --git a/server/service/rbac/role_service.go b/server/service/rbac/role_service.go
index 9bb24ee..98b3236 100644
--- a/server/service/rbac/role_service.go
+++ b/server/service/rbac/role_service.go
@@ -136,3 +136,11 @@ func illegalRoleCheck(role string) error {
 	}
 	return nil
 }
+
+func RoleUsage(ctx context.Context) (int64, error) {
+	_, used, err := rbac.Instance().ListRole(ctx)
+	if err != nil {
+		return 0, err
+	}
+	return used, nil
+}