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 4c344bc Fix: Service/Instance Quota incorrect (#1080)
4c344bc is described below
commit 4c344bcb68f486169ba4683aad45e6e7ab5e0c12
Author: little-cui <[email protected]>
AuthorDate: Fri Jul 2 08:59:55 2021 +0800
Fix: Service/Instance Quota incorrect (#1080)
* Fix: Service/Instance Quota incorrect
* Fix: optimize
---
datasource/etcd/ms.go | 40 +++++++++++----
datasource/mongo/client/dao/microservice.go | 8 +++
datasource/mongo/metrics.go | 7 +--
datasource/mongo/ops.go | 34 +++++++++++-
datasource/mongo/util/db.go | 23 ++++++++-
datasource/ms.go | 3 +-
server/plugin/quota/quota.go | 56 ++++++--------------
server/service/quota/quota.go | 80 +++++++++++++++++++++++++++++
8 files changed, 190 insertions(+), 61 deletions(-)
diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index 93f2c12..91e072e 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -68,7 +68,7 @@ func (ds *MetadataManager) RegisterService(ctx
context.Context, request *pb.Crea
remoteIP := util.GetIPFromContext(ctx)
service := request.Service
serviceFlag := util.StringJoin([]string{
- service.Environment, service.AppId, service.ServiceName,
service.Version}, "/")
+ service.Environment, service.AppId, service.ServiceName,
service.Version}, path.SPLIT)
domainProject := util.ParseDomainProject(ctx)
serviceKey := &pb.MicroServiceKey{
@@ -437,7 +437,7 @@ func (ds *MetadataManager) ExistService(ctx
context.Context, request *pb.GetExis
error) {
domainProject := util.ParseDomainProject(ctx)
serviceFlag := util.StringJoin([]string{
- request.Environment, request.AppId, request.ServiceName,
request.Version}, "/")
+ request.Environment, request.AppId, request.ServiceName,
request.Version}, path.SPLIT)
ids, exist, err := serviceUtil.FindServiceIds(ctx, request.Version,
&pb.MicroServiceKey{
Environment: request.Environment,
@@ -541,7 +541,7 @@ func (ds *MetadataManager) UnregisterService(ctx
context.Context, request *pb.De
}, err
}
-func (ds *MetadataManager) GetServiceCountByDomainProject(ctx context.Context,
request *pb.GetServiceCountRequest) (*pb.GetServiceCountResponse, error) {
+func (ds *MetadataManager) GetServiceCount(ctx context.Context, request
*pb.GetServiceCountRequest) (*pb.GetServiceCountResponse, error) {
domainProject := request.Domain
if request.Project != "" {
domainProject += path.SPLIT + request.Project
@@ -1070,7 +1070,7 @@ func (ds *MetadataManager) reshapeProviderKey(ctx
context.Context, provider *pb.
func (ds *MetadataManager) UpdateInstanceStatus(ctx context.Context, request
*pb.UpdateInstanceStatusRequest) (*pb.UpdateInstanceStatusResponse, error) {
domainProject := util.ParseDomainProject(ctx)
- updateStatusFlag := util.StringJoin([]string{request.ServiceId,
request.InstanceId, request.Status}, "/")
+ updateStatusFlag := util.StringJoin([]string{request.ServiceId,
request.InstanceId, request.Status}, path.SPLIT)
instance, err := serviceUtil.GetInstance(ctx, domainProject,
request.ServiceId, request.InstanceId)
if err != nil {
@@ -1109,7 +1109,7 @@ func (ds *MetadataManager) UpdateInstanceStatus(ctx
context.Context, request *pb
func (ds *MetadataManager) UpdateInstanceProperties(ctx context.Context,
request *pb.UpdateInstancePropsRequest) (
*pb.UpdateInstancePropsResponse, error) {
domainProject := util.ParseDomainProject(ctx)
- instanceFlag := util.StringJoin([]string{request.ServiceId,
request.InstanceId}, "/")
+ instanceFlag := util.StringJoin([]string{request.ServiceId,
request.InstanceId}, path.SPLIT)
instance, err := serviceUtil.GetInstance(ctx, domainProject,
request.ServiceId, request.InstanceId)
if err != nil {
@@ -1293,7 +1293,7 @@ func (ds *MetadataManager) UnregisterInstance(ctx
context.Context, request *pb.U
serviceID := request.ServiceId
instanceID := request.InstanceId
- instanceFlag := util.StringJoin([]string{serviceID, instanceID}, "/")
+ instanceFlag := util.StringJoin([]string{serviceID, instanceID},
path.SPLIT)
err := revokeInstance(ctx, domainProject, serviceID, instanceID)
if err != nil {
@@ -1317,7 +1317,7 @@ func (ds *MetadataManager) UnregisterInstance(ctx
context.Context, request *pb.U
func (ds *MetadataManager) Heartbeat(ctx context.Context, request
*pb.HeartbeatRequest) (*pb.HeartbeatResponse, error) {
remoteIP := util.GetIPFromContext(ctx)
domainProject := util.ParseDomainProject(ctx)
- instanceFlag := util.StringJoin([]string{request.ServiceId,
request.InstanceId}, "/")
+ instanceFlag := util.StringJoin([]string{request.ServiceId,
request.InstanceId}, path.SPLIT)
_, ttl, err := serviceUtil.HeartbeatUtil(ctx, domainProject,
request.ServiceId, request.InstanceId)
if err != nil {
@@ -1347,7 +1347,7 @@ func (ds *MetadataManager) Heartbeat(ctx context.Context,
request *pb.HeartbeatR
func (ds *MetadataManager) GetAllInstances(ctx context.Context, request
*pb.GetAllInstancesRequest) (*pb.GetAllInstancesResponse, error) {
domainProject := util.ParseDomainProject(ctx)
- key := path.GetInstanceRootKey(domainProject) + "/"
+ key := path.GetInstanceRootKey(domainProject) + path.SPLIT
opts := append(serviceUtil.FromContext(ctx), client.WithStrKey(key),
client.WithPrefix())
kvs, err := kv.Store().Instance().Search(ctx, opts...)
if err != nil {
@@ -1367,6 +1367,26 @@ func (ds *MetadataManager) GetAllInstances(ctx
context.Context, request *pb.GetA
return resp, nil
}
+func (ds *MetadataManager) GetInstanceCount(ctx context.Context, request
*pb.GetServiceCountRequest) (*pb.GetServiceCountResponse, error) {
+ domainProject := request.Domain
+ if request.Project != "" {
+ domainProject += path.SPLIT + request.Project
+ }
+ key := path.GetInstanceRootKey(domainProject) + path.SPLIT
+ opts := append(serviceUtil.FromContext(ctx),
+ client.WithStrKey(key),
+ client.WithPrefix(),
+ client.WithCountOnly())
+ kvs, err := kv.Store().Instance().Search(ctx, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return &pb.GetServiceCountResponse{
+ Response: pb.CreateResponse(pb.ResponseSuccess, "Get instance
count by domain/project successfully"),
+ Count: kvs.Count,
+ }, nil
+}
+
func (ds *MetadataManager) ModifySchemas(ctx context.Context, request
*pb.ModifySchemasRequest) (
*pb.ModifySchemasResponse, error) {
remoteIP := util.GetIPFromContext(ctx)
@@ -1713,7 +1733,7 @@ func (ds *MetadataManager) GetTags(ctx context.Context,
request *pb.GetServiceTa
func (ds *MetadataManager) UpdateTag(ctx context.Context, request
*pb.UpdateServiceTagRequest) (*pb.UpdateServiceTagResponse, error) {
var err error
remoteIP := util.GetIPFromContext(ctx)
- tagFlag := util.StringJoin([]string{request.Key, request.Value}, "/")
+ tagFlag := util.StringJoin([]string{request.Key, request.Value},
path.SPLIT)
domainProject := util.ParseDomainProject(ctx)
if !serviceUtil.ServiceExist(ctx, domainProject, request.ServiceId) {
@@ -2470,7 +2490,7 @@ func (ds *MetadataManager) DeleteServicePri(ctx
context.Context, serviceID strin
client.WithStrKey(path.GenerateServiceRuleKey(domainProject,
serviceID, "")),
client.WithPrefix()))
opts = append(opts, client.OpDel(client.WithStrKey(
-
util.StringJoin([]string{path.GetServiceRuleIndexRootKey(domainProject),
serviceID, ""}, "/")),
+
util.StringJoin([]string{path.GetServiceRuleIndexRootKey(domainProject),
serviceID, ""}, path.SPLIT)),
client.WithPrefix()))
//删除schemas
diff --git a/datasource/mongo/client/dao/microservice.go
b/datasource/mongo/client/dao/microservice.go
index 7cd39ec..2b2dccf 100644
--- a/datasource/mongo/client/dao/microservice.go
+++ b/datasource/mongo/client/dao/microservice.go
@@ -150,3 +150,11 @@ func GetServicesVersions(ctx context.Context, filter
interface{}) ([]string, err
}
return versions, nil
}
+
+func CountService(ctx context.Context, filter interface{}) (int64, error) {
+ count, err := client.GetMongoClient().Count(ctx,
model.CollectionService, filter)
+ if err != nil {
+ return 0, err
+ }
+ return count, nil
+}
diff --git a/datasource/mongo/metrics.go b/datasource/mongo/metrics.go
index aa394ab..db13b5d 100644
--- a/datasource/mongo/metrics.go
+++ b/datasource/mongo/metrics.go
@@ -57,17 +57,12 @@ func reportDomains(ctx context.Context, r
datasource.MetricsReporter) {
}
func reportServices(ctx context.Context, r datasource.MetricsReporter) {
- services, err := dao.GetServices(ctx, mutil.NewFilter())
+ services, err := dao.GetServices(ctx,
mutil.NewFilter(mutil.NotGlobal()))
if err != nil {
log.Error("query all services failed", err)
return
}
for _, service := range services {
- key :=
discovery.MicroServiceToKey(service.Domain+datasource.SPLIT+service.Project,
service.Service)
- if datasource.IsGlobal(key) {
- continue
- }
-
frameworkName, frameworkVersion :=
discovery.ToFrameworkLabel(service.Service)
labels := datasource.MetricsLabels{
Domain: service.Domain,
diff --git a/datasource/mongo/ops.go b/datasource/mongo/ops.go
index 68df783..8b6c391 100644
--- a/datasource/mongo/ops.go
+++ b/datasource/mongo/ops.go
@@ -20,9 +20,39 @@ package mongo
import (
"context"
+
"github.com/apache/servicecomb-service-center/datasource/mongo/client/dao"
+ mutil
"github.com/apache/servicecomb-service-center/datasource/mongo/util"
pb "github.com/go-chassis/cari/discovery"
)
-func (ds *MetadataManager) GetServiceCountByDomainProject(ctx context.Context,
request *pb.GetServiceCountRequest) (*pb.GetServiceCountResponse, error) {
- panic("implement me")
+func (ds *MetadataManager) GetServiceCount(ctx context.Context, request
*pb.GetServiceCountRequest) (
+ *pb.GetServiceCountResponse, error) {
+ options := []mutil.Option{mutil.NotGlobal(),
mutil.Domain(request.Domain)}
+ if request.Project != "" {
+ options = append(options, mutil.Project(request.Project))
+ }
+ count, err := dao.CountService(ctx, mutil.NewFilter(options...))
+ if err != nil {
+ return nil, err
+ }
+ return &pb.GetServiceCountResponse{
+ Response: pb.CreateResponse(pb.ResponseSuccess, "Get instance
count by domain/project successfully"),
+ Count: count,
+ }, nil
+}
+
+func (ds *MetadataManager) GetInstanceCount(ctx context.Context, request
*pb.GetServiceCountRequest) (
+ *pb.GetServiceCountResponse, error) {
+ options := []mutil.Option{mutil.Domain(request.Domain)}
+ if request.Project != "" {
+ options = append(options, mutil.Project(request.Project))
+ }
+ count, err := dao.CountInstance(ctx, mutil.NewFilter(options...))
+ if err != nil {
+ return nil, err
+ }
+ return &pb.GetServiceCountResponse{
+ Response: pb.CreateResponse(pb.ResponseSuccess, "Get instance
count by domain/project successfully"),
+ Count: count,
+ }, nil
}
diff --git a/datasource/mongo/util/db.go b/datasource/mongo/util/db.go
index c5c4c8f..a2dd0bf 100644
--- a/datasource/mongo/util/db.go
+++ b/datasource/mongo/util/db.go
@@ -25,6 +25,7 @@ import (
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/x/bsonx"
+ "github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/datasource/mongo/client/model"
"github.com/apache/servicecomb-service-center/pkg/util"
)
@@ -127,6 +128,12 @@ func Set(data interface{}) Option {
}
}
+func Nor(options ...Option) Option {
+ return func(filter bson.M) {
+ filter["$nor"] = bson.A{NewFilter(options...)}
+ }
+}
+
func NewFilter(options ...Option) bson.M {
filter := bson.M{}
for _, option := range options {
@@ -202,7 +209,7 @@ func ServiceProperty(property map[string]string) Option {
}
}
-func ServiceServiceName(serviceName string) Option {
+func ServiceServiceName(serviceName interface{}) Option {
return func(filter bson.M) {
filter[ConnectWithDot([]string{model.ColumnService,
model.ColumnServiceName})] = serviceName
}
@@ -356,3 +363,17 @@ func BuildIndexDoc(keys ...string) mongo.IndexModel {
}
return index
}
+
+func NotGlobal() Option {
+ var names []string
+ for name := range datasource.GlobalServiceNames {
+ names = append(names, name)
+ }
+ inFilter := NewFilter(In(names))
+ return Nor(
+ Domain(datasource.RegistryDomain),
+ Project(datasource.RegistryProject),
+ ServiceAppID(datasource.RegistryAppID),
+ ServiceServiceName(inFilter),
+ )
+}
diff --git a/datasource/ms.go b/datasource/ms.go
index 184a2e2..99ec56c 100644
--- a/datasource/ms.go
+++ b/datasource/ms.go
@@ -51,7 +51,7 @@ type MetadataManager interface {
UnregisterService(ctx context.Context, request
*pb.DeleteServiceRequest) (*pb.DeleteServiceResponse, error)
GetDeleteServiceFunc(ctx context.Context, serviceID string, force bool,
serviceRespChan chan<- *pb.DelServicesRspInfo)
func(context.Context)
- GetServiceCountByDomainProject(ctx context.Context,
+ GetServiceCount(ctx context.Context,
request *pb.GetServiceCountRequest)
(*pb.GetServiceCountResponse, error)
// Instance management
@@ -79,6 +79,7 @@ type MetadataManager interface {
BatchFind(ctx context.Context, request *pb.BatchFindInstancesRequest)
(*pb.BatchFindInstancesResponse, error)
// GetAllInstances returns instances under the specified domain
GetAllInstances(ctx context.Context, request
*pb.GetAllInstancesRequest) (*pb.GetAllInstancesResponse, error)
+ GetInstanceCount(ctx context.Context, request
*pb.GetServiceCountRequest) (*pb.GetServiceCountResponse, error)
// Schema management
ModifySchemas(ctx context.Context, request *pb.ModifySchemasRequest)
(*pb.ModifySchemasResponse, error)
diff --git a/server/plugin/quota/quota.go b/server/plugin/quota/quota.go
index b378ce7..1e114ef 100644
--- a/server/plugin/quota/quota.go
+++ b/server/plugin/quota/quota.go
@@ -23,15 +23,13 @@ import (
"fmt"
"strconv"
- pb "github.com/go-chassis/cari/discovery"
- "github.com/go-chassis/cari/pkg/errsvc"
-
- "github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/plugin"
"github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/config"
- "github.com/apache/servicecomb-service-center/server/metrics"
+ "github.com/apache/servicecomb-service-center/server/service/quota"
+ pb "github.com/go-chassis/cari/discovery"
+ "github.com/go-chassis/cari/pkg/errsvc"
)
const QUOTA plugin.Kind = "quota"
@@ -150,50 +148,26 @@ func GetResourceUsage(ctx context.Context, res
*ApplyQuotaResource) (int64, erro
serviceID := res.ServiceID
switch res.QuotaType {
case TypeService:
- return metrics.GetTotalService(util.ParseDomain(ctx), ""), nil
+ return quota.ServiceUsage(ctx, &pb.GetServiceCountRequest{
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ })
case TypeInstance:
- usage := metrics.GetTotalInstance(util.ParseDomain(ctx), "")
- return usage, nil
+ return quota.InstanceUsage(ctx, &pb.GetServiceCountRequest{
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ })
case TypeRule:
- {
- resp, err :=
datasource.GetMetadataManager().GetRules(ctx, &pb.GetServiceRulesRequest{
- ServiceId: serviceID,
- })
- if err != nil {
- return 0, err
- }
- return int64(len(resp.Rules)), nil
- }
+ return quota.RuleUsage(ctx, serviceID)
case TypeSchema:
- {
- resp, err :=
datasource.GetMetadataManager().GetAllSchemas(ctx, &pb.GetAllSchemaRequest{
- ServiceId: serviceID,
- WithSchema: false,
- })
- if err != nil {
- return 0, err
- }
- return int64(len(resp.Schemas)), nil
- }
+ return quota.SchemaUsage(ctx, serviceID)
case TypeTag:
// always re-create the service old tags
return 0, nil
case TypeRole:
- {
- _, used, err :=
datasource.GetRoleManager().ListRole(ctx)
- if err != nil {
- return 0, err
- }
- return used, nil
- }
+ return quota.RoleUsage(ctx)
case TypeAccount:
- {
- _, used, err :=
datasource.GetAccountManager().ListAccount(ctx)
- if err != nil {
- return 0, err
- }
- return used, nil
- }
+ return quota.AccountUsage(ctx)
default:
return 0, fmt.Errorf("not define quota type '%s'",
res.QuotaType)
}
diff --git a/server/service/quota/quota.go b/server/service/quota/quota.go
new file mode 100644
index 0000000..53bf500
--- /dev/null
+++ b/server/service/quota/quota.go
@@ -0,0 +1,80 @@
+/*
+ * 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 quota
+
+import (
+ "context"
+
+ "github.com/apache/servicecomb-service-center/datasource"
+ "github.com/go-chassis/cari/discovery"
+)
+
+func ServiceUsage(ctx context.Context, request
*discovery.GetServiceCountRequest) (int64, error) {
+ resp, err := datasource.GetMetadataManager().GetServiceCount(ctx,
+ request)
+ if err != nil {
+ return 0, err
+ }
+ return resp.Count, nil
+}
+
+func InstanceUsage(ctx context.Context, request
*discovery.GetServiceCountRequest) (int64, error) {
+ resp, err := datasource.GetMetadataManager().GetInstanceCount(ctx,
+ request)
+ if err != nil {
+ return 0, err
+ }
+ return resp.Count, nil
+}
+
+func RuleUsage(ctx context.Context, serviceID string) (int64, error) {
+ resp, err := datasource.GetMetadataManager().GetRules(ctx,
&discovery.GetServiceRulesRequest{
+ ServiceId: serviceID,
+ })
+ if err != nil {
+ return 0, err
+ }
+ return int64(len(resp.Rules)), nil
+}
+
+func SchemaUsage(ctx context.Context, serviceID string) (int64, error) {
+ resp, err := datasource.GetMetadataManager().GetAllSchemas(ctx,
&discovery.GetAllSchemaRequest{
+ ServiceId: serviceID,
+ WithSchema: false,
+ })
+ if err != nil {
+ return 0, err
+ }
+ return int64(len(resp.Schemas)), nil
+}
+
+func RoleUsage(ctx context.Context) (int64, error) {
+ _, used, err := datasource.GetRoleManager().ListRole(ctx)
+ if err != nil {
+ return 0, err
+ }
+ return used, nil
+}
+
+func AccountUsage(ctx context.Context) (int64, error) {
+ _, used, err := datasource.GetAccountManager().ListAccount(ctx)
+ if err != nil {
+ return 0, err
+ }
+ return used, nil
+}