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
+}

Reply via email to