Refactor quota mgr (#1181)
* Refactor quota mgr
* Add UTs
diff --git a/datasource/engine.go b/datasource/engine.go
index 667d0db..d2c3265 100644
--- a/datasource/engine.go
+++ b/datasource/engine.go
@@ -19,7 +19,6 @@
import (
"context"
- "time"
"github.com/little-cui/etcdadpt"
)
@@ -28,8 +27,6 @@
type SCManager interface {
SelfRegister(ctx context.Context) error
SelfUnregister(ctx context.Context) error
- // OPS
- ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error
UpgradeVersion(ctx context.Context) error
GetClusters(ctx context.Context) (etcdadpt.Clusters, error)
}
diff --git a/datasource/engine_test.go b/datasource/engine_test.go
index 5a828bd..cc3a048 100644
--- a/datasource/engine_test.go
+++ b/datasource/engine_test.go
@@ -20,11 +20,9 @@
import (
"context"
"fmt"
- "time"
"github.com/apache/servicecomb-service-center/datasource/etcd/path"
- "github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/pkg/util"
apt "github.com/apache/servicecomb-service-center/server/core"
pb "github.com/go-chassis/cari/discovery"
@@ -98,31 +96,3 @@
Expect(getSvcResp.Response.GetCode() == pb.ResponseSuccess).To(Equal(!v.ShouldClear))
}
}
-
-func serviceClearCheckFunc(domain string, project string) func() {
- return func() {
- var err error
- It("should run clear task success", func() {
- withInstance := true
- withNoInstance := false
- shouldClear := true
- shouldNotClear := false
-
- createService(domain, project, "svc1", withNoInstance, shouldClear)
- createService(domain, project, "svc2", withInstance, shouldNotClear)
- time.Sleep(2 * time.Second)
- createService(domain, project, "svc3", withNoInstance, shouldNotClear)
- createService(domain, project, "svc4", withInstance, shouldNotClear)
-
- err = datasource.GetSCManager().ClearNoInstanceServices(context.Background(), 2*time.Second)
- Expect(err).To(BeNil())
-
- checkServiceCleared(domain, project)
- })
- }
-}
-
-var _ = Describe("clear service", func() {
- Describe("domain project 1", serviceClearCheckFunc("default1", "default"))
- Describe("domain project 2", serviceClearCheckFunc("default2", "default"))
-})
diff --git a/datasource/etcd/engine.go b/datasource/etcd/engine.go
index 0ddb226..3666aa3 100644
--- a/datasource/etcd/engine.go
+++ b/datasource/etcd/engine.go
@@ -23,16 +23,12 @@
"errors"
"fmt"
"os"
- "strconv"
- "strings"
"time"
"github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/datasource/etcd/mux"
"github.com/apache/servicecomb-service-center/datasource/etcd/path"
- serviceUtil "github.com/apache/servicecomb-service-center/datasource/etcd/util"
"github.com/apache/servicecomb-service-center/pkg/log"
- "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"
@@ -176,98 +172,6 @@
return nil
}
-// ClearNoInstanceService clears services which have no instance
-func (sm *SCManager) ClearNoInstanceServices(ctx context.Context, serviceTTL time.Duration) error {
- services, err := serviceUtil.GetAllServicesAcrossDomainProject(ctx)
- if err != nil {
- return err
- }
- if len(services) == 0 {
- log.Info("no service found, no need to clear")
- return nil
- }
- timeLimit := time.Now().Add(0 - serviceTTL)
- log.Info(fmt.Sprintf("clear no-instance services created before %s", timeLimit))
- timeLimitStamp := strconv.FormatInt(timeLimit.Unix(), 10)
-
- for domainProject, svcList := range services {
- if len(svcList) == 0 {
- continue
- }
- ctx, err := ctxFromDomainProject(ctx, domainProject)
- if err != nil {
- log.Error("get domain project context failed", err)
- continue
- }
- for _, svc := range svcList {
- if svc == nil {
- continue
- }
- ok, err := shouldClear(ctx, timeLimitStamp, svc)
- if err != nil {
- log.Error("check service clear necessity failed", err)
- continue
- }
- if !ok {
- continue
- }
- //delete this service
- svcCtxStr := "domainProject: " + domainProject + ", " +
- "env: " + svc.Environment + ", " +
- "service: " + util.StringJoin([]string{svc.AppId, svc.ServiceName, svc.Version}, path.SPLIT)
- delSvcReq := &pb.DeleteServiceRequest{
- ServiceId: svc.ServiceId,
- Force: true, //force delete
- }
- delSvcResp, err := core.ServiceAPI.Delete(ctx, delSvcReq)
- if err != nil {
- log.Error(fmt.Sprintf("clear service failed, %s", svcCtxStr), err)
- continue
- }
- if delSvcResp.Response.GetCode() != pb.ResponseSuccess {
- log.Error(fmt.Sprintf("clear service failed, %s, %s", delSvcResp.Response.GetMessage(), svcCtxStr), err)
- continue
- }
- log.Warn(fmt.Sprintf("clear service success, %s", svcCtxStr))
- }
- }
- return nil
-}
-
-func ctxFromDomainProject(pCtx context.Context, domainProject string) (ctx context.Context, err error) {
- splitIndex := strings.Index(domainProject, path.SPLIT)
- if splitIndex == -1 {
- return nil, errors.New("invalid domainProject: " + domainProject)
- }
- domain := domainProject[:splitIndex]
- project := domainProject[splitIndex+1:]
- return util.SetDomainProject(pCtx, domain, project), nil
-}
-
-//check whether a service should be cleared
-func shouldClear(ctx context.Context, timeLimitStamp string, svc *pb.MicroService) (bool, error) {
- //ignore a service if it is created after timeLimitStamp
- if svc.Timestamp > timeLimitStamp {
- return false, nil
- }
- getInstsReq := &pb.GetInstancesRequest{
- ConsumerServiceId: svc.ServiceId,
- ProviderServiceId: svc.ServiceId,
- }
- getInstsResp, err := discosvc.GetInstances(ctx, getInstsReq)
- if err != nil {
- return false, err
- }
- if getInstsResp.Response.GetCode() != pb.ResponseSuccess {
- return false, errors.New("get instance failed: " + getInstsResp.Response.GetMessage())
- }
- //ignore a service if it has instances
- if len(getInstsResp.Instances) > 0 {
- return false, nil
- }
- return true, nil
-}
-
func (sm *SCManager) GetClusters(ctx context.Context) (etcdadpt.Clusters, error) {
return etcdadpt.ListCluster(ctx)
}
diff --git a/datasource/etcd/etcd_suite_test.go b/datasource/etcd/etcd_suite_test.go
index 02a0304..c6dddb3 100644
--- a/datasource/etcd/etcd_suite_test.go
+++ b/datasource/etcd/etcd_suite_test.go
@@ -20,25 +20,15 @@
import (
"context"
"testing"
- "time"
_ "github.com/apache/servicecomb-service-center/test"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
- "github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/pkg/util"
"github.com/onsi/ginkgo/reporters"
)
-var timeLimit = 2 * time.Second
-
-var _ = BeforeSuite(func() {
- //clear service created in last test
- time.Sleep(timeLimit)
- _ = datasource.GetSCManager().ClearNoInstanceServices(context.Background(), timeLimit)
-})
-
func TestEtcd(t *testing.T) {
RegisterFailHandler(Fail)
junitReporter := reporters.NewJUnitReporter("etcd.junit.xml")
diff --git a/datasource/etcd/event/instance_event_handler.go b/datasource/etcd/event/instance_event_handler.go
index 8310910..5e35643 100644
--- a/datasource/etcd/event/instance_event_handler.go
+++ b/datasource/etcd/event/instance_event_handler.go
@@ -31,6 +31,7 @@
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/event"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/apache/servicecomb-service-center/server/syncernotify"
pb "github.com/go-chassis/cari/discovery"
)
@@ -68,8 +69,7 @@
if action == pb.EVT_DELETE && !datasource.IsDefaultDomainProject(domainProject) {
domain, project := path.SplitDomainProject(domainProject)
- serviceUtil.RemandInstanceQuota(
- util.SetDomainProject(context.Background(), domain, project))
+ quotasvc.RemandInstance(util.SetDomainProject(context.Background(), domain, project))
}
// 查询服务版本信息
diff --git a/datasource/etcd/ms.go b/datasource/etcd/ms.go
index d0b129f..6d5483b 100644
--- a/datasource/etcd/ms.go
+++ b/datasource/etcd/ms.go
@@ -34,8 +34,8 @@
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/core"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
"github.com/apache/servicecomb-service-center/server/plugin/uuid"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
pb "github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/pkg/errsvc"
"github.com/go-chassis/foundation/gopool"
@@ -1759,8 +1759,7 @@
pluginOps := make([]etcdadpt.OpOptions, 0)
if !ds.isSchemaEditable() {
if len(service.Schemas) == 0 {
- res := quota.NewApplyQuotaResource(quota.TypeSchema, domainProject, serviceID, int64(len(nonExistSchemaIds)))
- errQuota := quota.Apply(ctx, res)
+ errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(len(nonExistSchemaIds)))
if errQuota != nil {
log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
return errQuota
@@ -1803,8 +1802,7 @@
} else {
quotaSize := len(needAddSchemas) - len(needDeleteSchemas)
if quotaSize > 0 {
- res := quota.NewApplyQuotaResource(quota.TypeSchema, domainProject, serviceID, int64(quotaSize))
- errQuota := quota.Apply(ctx, res)
+ errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(quotaSize))
if errQuota != nil {
log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
return errQuota
@@ -2073,26 +2071,8 @@
return pb.CreateResponse(pb.ErrServiceNotExists, "Service does not exist."), nil
}
- serviceUtil.RemandServiceQuota(ctx)
+ quotasvc.RemandService(ctx)
log.Info(fmt.Sprintf("%s micro-service[%s] successfully, operator: %s", title, serviceID, remoteIP))
return pb.CreateResponse(pb.ResponseSuccess, "Unregister service successfully."), nil
}
-
-func (ds *MetadataManager) GetDeleteServiceFunc(ctx context.Context, serviceID string, force bool,
- serviceRespChan chan<- *pb.DelServicesRspInfo) func(context.Context) {
- return func(_ context.Context) {
- serviceRst := &pb.DelServicesRspInfo{
- ServiceId: serviceID,
- ErrMessage: "",
- }
- resp, err := ds.DeleteServicePri(ctx, serviceID, force)
- if err != nil {
- serviceRst.ErrMessage = err.Error()
- } else if resp.GetCode() != pb.ResponseSuccess {
- serviceRst.ErrMessage = resp.GetMessage()
- }
-
- serviceRespChan <- serviceRst
- }
-}
diff --git a/datasource/etcd/util/microservice_util.go b/datasource/etcd/util/microservice_util.go
index 6ae8d11..997a6f5 100644
--- a/datasource/etcd/util/microservice_util.go
+++ b/datasource/etcd/util/microservice_util.go
@@ -30,7 +30,6 @@
"github.com/apache/servicecomb-service-center/pkg/log"
"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"
pb "github.com/go-chassis/cari/discovery"
"github.com/little-cui/etcdadpt"
)
@@ -238,14 +237,6 @@
return services, nil
}
-func RemandServiceQuota(ctx context.Context) {
- quota.Remand(ctx, quota.TypeService)
-}
-
-func RemandInstanceQuota(ctx context.Context) {
- quota.Remand(ctx, quota.TypeInstance)
-}
-
func UpdateService(domainProject string, serviceID string, service *pb.MicroService) (opt etcdadpt.OpOptions, err error) {
opt = etcdadpt.OpOptions{}
key := path.GenerateServiceKey(domainProject, serviceID)
diff --git a/datasource/etcd/util/util_test.go b/datasource/etcd/util/util_test.go
index 50c0eb0..84a8e38 100644
--- a/datasource/etcd/util/util_test.go
+++ b/datasource/etcd/util/util_test.go
@@ -169,8 +169,3 @@
t.Fatalf("TestFromContext failed")
}
}
-
-func TestRemandQuota(t *testing.T) {
- serviceUtil.RemandServiceQuota(context.Background())
- serviceUtil.RemandInstanceQuota(context.Background())
-}
diff --git a/datasource/mongo/engine.go b/datasource/mongo/engine.go
index 900bec0..a5eb730 100644
--- a/datasource/mongo/engine.go
+++ b/datasource/mongo/engine.go
@@ -20,17 +20,11 @@
import (
"context"
"fmt"
- "strconv"
- "strings"
"time"
"github.com/apache/servicecomb-service-center/datasource"
- "github.com/apache/servicecomb-service-center/datasource/etcd/path"
- "github.com/apache/servicecomb-service-center/datasource/mongo/client"
- "github.com/apache/servicecomb-service-center/datasource/mongo/client/model"
mutil "github.com/apache/servicecomb-service-center/datasource/mongo/util"
"github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/core"
"github.com/apache/servicecomb-service-center/server/metrics"
discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
@@ -79,64 +73,6 @@
return nil
}
-// OPS
-func (ds *SCManager) ClearNoInstanceServices(ctx context.Context, ttl time.Duration) error {
- services, err := GetAllServicesAcrossDomainProject(ctx)
- if err != nil {
- return err
- }
- if len(services) == 0 {
- log.Info("no service found, no need to clear")
- return nil
- }
-
- timeLimit := time.Now().Add(0 - ttl)
- log.Info(fmt.Sprintf("clear no-instance services created before %s", timeLimit))
- timeLimitStamp := strconv.FormatInt(timeLimit.Unix(), 10)
-
- for domainProject, svcList := range services {
- if len(svcList) == 0 {
- continue
- }
- ctx, err := ctxFromDomainProject(ctx, domainProject)
- if err != nil {
- log.Error("get domain project context failed", err)
- continue
- }
- for _, svc := range svcList {
- if svc == nil {
- continue
- }
- ok, err := shouldClear(ctx, timeLimitStamp, svc)
- if err != nil {
- log.Error("check service clear necessity failed", err)
- continue
- }
- if !ok {
- continue
- }
- svcCtxStr := "domainProject: " + domainProject + ", " +
- "env: " + svc.Environment + ", " +
- "service: " + util.StringJoin([]string{svc.AppId, svc.ServiceName, svc.Version}, path.SPLIT)
- delSvcReq := &pb.DeleteServiceRequest{
- ServiceId: svc.ServiceId,
- Force: true, //force delete
- }
- delSvcResp, err := datasource.GetMetadataManager().UnregisterService(ctx, delSvcReq)
- if err != nil {
- log.Error(fmt.Sprintf("clear service failed, %s", svcCtxStr), err)
- continue
- }
- if delSvcResp.Response.GetCode() != pb.ResponseSuccess {
- log.Error(fmt.Sprintf("clear service failed %s %s", delSvcResp.Response.GetMessage(), svcCtxStr), err)
- continue
- }
- log.Warn(fmt.Sprintf("clear service success, %s", svcCtxStr))
- }
- }
- return nil
-}
-
func (ds *SCManager) UpgradeVersion(ctx context.Context) error {
return nil
}
@@ -235,59 +171,3 @@
}
})
}
-
-func GetAllServicesAcrossDomainProject(ctx context.Context) (map[string][]*pb.MicroService, error) {
- filter := mutil.NewBasicFilter(ctx)
-
- findRes, err := client.GetMongoClient().Find(ctx, model.CollectionService, filter)
- if err != nil {
- return nil, err
- }
-
- services := make(map[string][]*pb.MicroService)
-
- for findRes.Next(ctx) {
- var mongoService model.Service
- err := findRes.Decode(&mongoService)
- if err != nil {
- return nil, err
- }
- domainProject := mongoService.Domain + "/" + mongoService.Project
- services[domainProject] = append(services[domainProject], mongoService.Service)
- }
- return services, nil
-}
-
-func ctxFromDomainProject(pCtx context.Context, domainProject string) (ctx context.Context, err error) {
- splitIndex := strings.Index(domainProject, path.SPLIT)
- if splitIndex == -1 {
- return nil, mutil.NewError("invalid domainProject: ", domainProject)
- }
- domain := domainProject[:splitIndex]
- project := domainProject[splitIndex+1:]
- return util.SetDomainProject(pCtx, domain, project), nil
-}
-
-func shouldClear(ctx context.Context, timeLimitStamp string, svc *pb.MicroService) (bool, error) {
- if svc.Timestamp > timeLimitStamp {
- return false, nil
- }
-
- getInstsReq := &pb.GetInstancesRequest{
- ConsumerServiceId: svc.ServiceId,
- ProviderServiceId: svc.ServiceId,
- }
-
- getInstsResp, err := datasource.GetMetadataManager().GetInstances(ctx, getInstsReq)
- if err != nil {
- return false, err
- }
- if getInstsResp.Response.GetCode() != pb.ResponseSuccess {
- return false, mutil.NewError("get instance failed: ", getInstsResp.Response.GetMessage())
- }
- //ignore a service if it has instances
- if len(getInstsResp.Instances) > 0 {
- return false, nil
- }
- return true, nil
-}
diff --git a/datasource/mongo/mongo_test.go b/datasource/mongo/mongo_test.go
index c573034..d11f6e9 100644
--- a/datasource/mongo/mongo_test.go
+++ b/datasource/mongo/mongo_test.go
@@ -20,23 +20,12 @@
// initialize
import (
"context"
- "testing"
- "time"
_ "github.com/apache/servicecomb-service-center/test"
- "github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/pkg/util"
)
-var timeLimit = 2 * time.Second
-
func getContext() context.Context {
return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
}
-
-func TestMongo(t *testing.T) {
- //clear service created in last test
- time.Sleep(timeLimit)
- _ = datasource.GetSCManager().ClearNoInstanceServices(getContext(), timeLimit)
-}
diff --git a/datasource/mongo/ms.go b/datasource/mongo/ms.go
index d489327..c85620d 100644
--- a/datasource/mongo/ms.go
+++ b/datasource/mongo/ms.go
@@ -38,8 +38,8 @@
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/util"
apt "github.com/apache/servicecomb-service-center/server/core"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
"github.com/apache/servicecomb-service-center/server/plugin/uuid"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/pkg/errsvc"
"github.com/go-chassis/foundation/gopool"
@@ -378,23 +378,6 @@
}, nil
}
-func (ds *MetadataManager) GetDeleteServiceFunc(ctx context.Context, serviceID string, force bool, serviceRespChan chan<- *discovery.DelServicesRspInfo) func(context.Context) {
- return func(_ context.Context) {
- serviceRst := &discovery.DelServicesRspInfo{
- ServiceId: serviceID,
- ErrMessage: "",
- }
- resp, err := ds.DelServicePri(ctx, serviceID, force)
- if err != nil {
- serviceRst.ErrMessage = err.Error()
- } else if resp.GetCode() != discovery.ResponseSuccess {
- serviceRst.ErrMessage = resp.GetMessage()
- }
-
- serviceRespChan <- serviceRst
- }
-}
-
func (ds *MetadataManager) GetServiceDetail(ctx context.Context, request *discovery.GetServiceRequest) (
*discovery.ServiceDetail, error) {
mgSvc, err := GetServiceByID(ctx, request.ServiceId)
@@ -831,8 +814,7 @@
var serviceOps []mongo.WriteModel
if !ds.isSchemaEditable() {
if len(service.Schemas) == 0 {
- res := quota.NewApplyQuotaResource(quota.TypeSchema, util.ParseDomainProject(ctx), serviceID, int64(len(nonExistSchemaIds)))
- errQuota := quota.Apply(ctx, res)
+ errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(len(nonExistSchemaIds)))
if errQuota != nil {
log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
return errQuota
@@ -883,8 +865,7 @@
} else {
quotaSize := len(needAddSchemas) - len(needDeleteSchemas)
if quotaSize > 0 {
- res := quota.NewApplyQuotaResource(quota.TypeSchema, util.ParseDomainProject(ctx), serviceID, int64(quotaSize))
- errQuota := quota.Apply(ctx, res)
+ errQuota := quotasvc.ApplySchema(ctx, serviceID, int64(quotaSize))
if errQuota != nil {
log.Error(fmt.Sprintf("modify service[%s] schemas failed, operator: %s", serviceID, remoteIP), errQuota)
return errQuota
diff --git a/datasource/ms.go b/datasource/ms.go
index 0e1f481..1907939 100644
--- a/datasource/ms.go
+++ b/datasource/ms.go
@@ -55,8 +55,6 @@
ExistService(ctx context.Context, request *pb.GetExistenceRequest) (*pb.GetExistenceResponse, error)
UpdateService(ctx context.Context, request *pb.UpdateServicePropsRequest) (*pb.UpdateServicePropsResponse, error)
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)
GetServiceCount(ctx context.Context,
request *pb.GetServiceCountRequest) (*pb.GetServiceCountResponse, error)
diff --git a/datasource/schema_test.go b/datasource/schema_test.go
index 15a9d5c..088601c 100644
--- a/datasource/schema_test.go
+++ b/datasource/schema_test.go
@@ -25,7 +25,7 @@
"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"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
pb "github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/pkg/errsvc"
"github.com/go-chassis/go-archaius"
@@ -72,7 +72,8 @@
t.Run("create schemas out of gauge", func(t *testing.T) {
log.Info("create schemas out of gauge")
- size := quota.DefaultSchemaQuota + 1
+ max := int(quotasvc.SchemaQuota())
+ size := max + 1
schemaIds := make([]string, 0, size)
schemas := make([]*pb.Schema, 0, size)
for i := 0; i < size; i++ {
@@ -98,7 +99,7 @@
log.Info("batch modify schemas 2")
resp, err = datasource.GetMetadataManager().ModifySchemas(getContext(), &pb.ModifySchemasRequest{
ServiceId: serviceIdDev,
- Schemas: schemas[:quota.DefaultSchemaQuota],
+ Schemas: schemas[:max],
})
assert.NoError(t, err)
assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
diff --git a/datasource/service_test.go b/datasource/service_test.go
index 99fa162..e3e78db 100644
--- a/datasource/service_test.go
+++ b/datasource/service_test.go
@@ -24,19 +24,19 @@
"testing"
"time"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"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/util"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
pb "github.com/go-chassis/cari/discovery"
"github.com/stretchr/testify/assert"
)
func TestService_Register(t *testing.T) {
t.Run("Register service after init & install, should pass", func(t *testing.T) {
- size := quota.DefaultSchemaQuota + 1
+ size := int(quotasvc.SchemaQuota()) + 1
paths := make([]*pb.ServicePath, 0, size)
properties := make(map[string]string, size)
for i := 0; i < size; i++ {
diff --git a/datasource/tag_test.go b/datasource/tag_test.go
index a2b42c6..204c717 100644
--- a/datasource/tag_test.go
+++ b/datasource/tag_test.go
@@ -23,9 +23,9 @@
"testing"
"github.com/apache/servicecomb-service-center/datasource"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"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/stretchr/testify/assert"
)
@@ -66,7 +66,7 @@
t.Run("the request is valid", func(t *testing.T) {
log.Info("tag quota is equal to the default value and should be paas")
- defaultQuota := quota.DefaultTagQuota
+ defaultQuota := int(quotasvc.TagQuota())
tags := make(map[string]string, defaultQuota)
for i := 0; i < defaultQuota; i++ {
s := "tag" + strconv.Itoa(i)
diff --git a/server/metrics/meta_reporter.go b/server/metrics/meta_reporter.go
index 97ef861..4463d10 100644
--- a/server/metrics/meta_reporter.go
+++ b/server/metrics/meta_reporter.go
@@ -24,7 +24,7 @@
"github.com/apache/servicecomb-service-center/pkg/log"
metricsvc "github.com/apache/servicecomb-service-center/pkg/metrics"
promutil "github.com/apache/servicecomb-service-center/pkg/prometheus"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/go-chassis/go-chassis/v2/pkg/metrics"
)
@@ -61,7 +61,7 @@
"instance": instance,
}
used := promutil.GaugeValue(KeyServiceTotal, labels)
- total := float64(quota.DefaultServiceQuota)
+ total := float64(quotasvc.ServiceQuota())
if total <= 0 {
return
}
@@ -88,7 +88,7 @@
"instance": instance,
}
used := promutil.GaugeValue(KeyInstanceTotal, labels)
- total := float64(quota.DefaultInstanceQuota)
+ total := float64(quotasvc.InstanceQuota())
if total <= 0 {
return
}
diff --git a/server/metrics/meta_reporter_test.go b/server/metrics/meta_reporter_test.go
index 29639da..bdc5a9b 100644
--- a/server/metrics/meta_reporter_test.go
+++ b/server/metrics/meta_reporter_test.go
@@ -23,9 +23,11 @@
_ "github.com/apache/servicecomb-service-center/test"
"github.com/apache/servicecomb-service-center/datasource"
+ "github.com/apache/servicecomb-service-center/pkg/plugin"
promutil "github.com/apache/servicecomb-service-center/pkg/prometheus"
"github.com/apache/servicecomb-service-center/server/metrics"
"github.com/apache/servicecomb-service-center/server/plugin/quota"
+ "github.com/apache/servicecomb-service-center/server/plugin/quota/buildin"
"github.com/stretchr/testify/assert"
)
@@ -35,20 +37,21 @@
reporter := metrics.MetaReporter{}
assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
- old := quota.DefaultServiceQuota
- quota.DefaultServiceQuota = 0
+ inst := plugin.Plugins().Instance(quota.QUOTA).(*buildin.Quota)
+ old := inst.ServiceQuota
+ inst.ServiceQuota = 0
reporter.ServiceUsageSet()
assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
- quota.DefaultServiceQuota = old
+ inst.ServiceQuota = old
reporter.ServiceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P1"})
reporter.ServiceUsageSet()
- assert.Equal(t, 1/float64(quota.DefaultServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
+ assert.Equal(t, 1/float64(inst.ServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
reporter.ServiceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P2"})
reporter.ServiceAdd(1, datasource.MetricsLabels{Domain: "D2", Project: "P3"})
reporter.ServiceUsageSet()
- assert.Equal(t, 3/float64(quota.DefaultServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
+ assert.Equal(t, 3/float64(inst.ServiceQuota), promutil.GaugeValue(metrics.KeyServiceUsage, labels))
}
func TestMetaReporter_InstanceUsageSet(t *testing.T) {
@@ -57,18 +60,19 @@
reporter := metrics.MetaReporter{}
assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
- old := quota.DefaultInstanceQuota
- quota.DefaultInstanceQuota = 0
+ inst := plugin.Plugins().Instance(quota.QUOTA).(*buildin.Quota)
+ old := inst.InstanceQuota
+ inst.InstanceQuota = 0
reporter.InstanceUsageSet()
assert.Equal(t, float64(0), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
- quota.DefaultInstanceQuota = old
+ inst.InstanceQuota = old
reporter.InstanceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P1"})
reporter.InstanceUsageSet()
- assert.Equal(t, 1/float64(quota.DefaultInstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
+ assert.Equal(t, 1/float64(inst.InstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
reporter.InstanceAdd(1, datasource.MetricsLabels{Domain: "D1", Project: "P2"})
reporter.InstanceAdd(1, datasource.MetricsLabels{Domain: "D2", Project: "P3"})
reporter.InstanceUsageSet()
- assert.Equal(t, 3/float64(quota.DefaultInstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
+ assert.Equal(t, 3/float64(inst.InstanceQuota), promutil.GaugeValue(metrics.KeyInstanceUsage, labels))
}
diff --git a/server/plugin/quota/buildin/account.go b/server/plugin/quota/buildin/account.go
new file mode 100644
index 0000000..3fa5f42
--- /dev/null
+++ b/server/plugin/quota/buildin/account.go
@@ -0,0 +1,32 @@
+/*
+ * 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"
+)
+
+func AccountUsage(ctx context.Context) (int64, error) {
+ _, used, err := datasource.GetAccountManager().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 3a6b1c7..5068687 100644
--- a/server/plugin/quota/buildin/buildin.go
+++ b/server/plugin/quota/buildin/buildin.go
@@ -23,7 +23,20 @@
"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/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
+ pb "github.com/go-chassis/cari/discovery"
+)
+
+const (
+ defaultServiceLimit int64 = 50000
+ defaultInstanceLimit int64 = 150000
+ defaultSchemaLimit int64 = 100
+ defaultTagLimit int64 = 100
+ defaultAccountLimit int64 = 1000
+ defaultRoleLimit int64 = 100
)
func init() {
@@ -31,42 +44,80 @@
}
func New() plugin.Instance {
- quota.Init()
+ q := &Quota{
+ ServiceQuota: config.GetInt64("quota.cap.service.limit", defaultServiceLimit, config.WithENV("QUOTA_SERVICE")),
+ InstanceQuota: config.GetInt64("quota.cap.instance.limit", defaultInstanceLimit, config.WithENV("QUOTA_INSTANCE")),
+ SchemaQuota: config.GetInt64("quota.cap.schema.limit", defaultSchemaLimit, config.WithENV("QUOTA_SCHEMA")),
+ TagQuota: config.GetInt64("quota.cap.tag.limit", defaultTagLimit, config.WithENV("QUOTA_TAG")),
+ AccountQuota: config.GetInt64("quota.cap.account.limit", defaultAccountLimit, config.WithENV("QUOTA_ACCOUNT")),
+ RoleQuota: config.GetInt64("quota.cap.role.limit", defaultRoleLimit, config.WithENV("QUOTA_ROLE")),
+ }
log.Info(fmt.Sprintf("quota init, service: %d, instance: %d, schema: %d/service, tag: %d/service"+
", account: %d, role: %d",
- quota.DefaultServiceQuota, quota.DefaultInstanceQuota,
- quota.DefaultSchemaQuota, quota.DefaultTagQuota,
- quota.DefaultAccountQuota, quota.DefaultRoleQuota))
- return &Quota{}
+ q.ServiceQuota, q.InstanceQuota, q.SchemaQuota, q.TagQuota,
+ q.AccountQuota, q.RoleQuota))
+ return q
}
type Quota struct {
+ ServiceQuota int64
+ InstanceQuota int64
+ SchemaQuota int64
+ TagQuota int64
+ AccountQuota int64
+ RoleQuota int64
}
func (q *Quota) GetQuota(ctx context.Context, t quota.ResourceType) int64 {
switch t {
- case quota.TypeInstance:
- return int64(quota.DefaultInstanceQuota)
- case quota.TypeService:
- return int64(quota.DefaultServiceQuota)
- case quota.TypeSchema:
- return int64(quota.DefaultSchemaQuota)
- case quota.TypeTag:
- return int64(quota.DefaultTagQuota)
- case quota.TypeAccount:
- return int64(quota.DefaultAccountQuota)
- case quota.TypeRole:
- return int64(quota.DefaultRoleQuota)
+ case quotasvc.TypeInstance:
+ return q.InstanceQuota
+ case quotasvc.TypeService:
+ return q.ServiceQuota
+ case quotasvc.TypeSchema:
+ return q.SchemaQuota
+ case quotasvc.TypeTag:
+ return q.TagQuota
+ case quotasvc.TypeAccount:
+ return q.AccountQuota
+ case quotasvc.TypeRole:
+ return q.RoleQuota
default:
return 0
}
}
//向配额中心上报配额使用量
-func (q *Quota) RemandQuotas(ctx context.Context, quotaType quota.ResourceType) {
+func (q *Quota) RemandQuotas(ctx context.Context, resourceType quota.ResourceType) {
df, ok := plugin.DynamicPluginFunc(quota.QUOTA, "RemandQuotas").(func(context.Context, quota.ResourceType))
if ok {
- df(ctx, quotaType)
+ df(ctx, resourceType)
return
}
}
+
+func (q *Quota) Usage(ctx context.Context, req *quota.Request) (int64, error) {
+ switch req.QuotaType {
+ case quotasvc.TypeInstance:
+ return InstanceUsage(ctx, &pb.GetServiceCountRequest{
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ })
+ case quotasvc.TypeService:
+ return ServiceUsage(ctx, &pb.GetServiceCountRequest{
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ })
+ case quotasvc.TypeSchema:
+ return SchemaUsage(ctx, req.ServiceID)
+ case quotasvc.TypeTag:
+ // always re-create the service old tags
+ return 0, nil
+ case quotasvc.TypeAccount:
+ return AccountUsage(ctx)
+ case quotasvc.TypeRole:
+ return RoleUsage(ctx)
+ default:
+ return 0, nil
+ }
+}
diff --git a/server/plugin/quota/buildin/buildin_test.go b/server/plugin/quota/buildin/buildin_test.go
deleted file mode 100644
index f8c2936..0000000
--- a/server/plugin/quota/buildin/buildin_test.go
+++ /dev/null
@@ -1,85 +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/server/init"
-
- _ "github.com/apache/servicecomb-service-center/server/bootstrap"
-
- "github.com/apache/servicecomb-service-center/datasource"
- "github.com/apache/servicecomb-service-center/pkg/util"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
- discosvc "github.com/apache/servicecomb-service-center/server/service/disco"
- pb "github.com/go-chassis/cari/discovery"
- "github.com/go-chassis/go-archaius"
- "github.com/little-cui/etcdadpt"
- "github.com/stretchr/testify/assert"
-)
-
-func init() {
- archaius.Set("registry.cache.mode", 0)
- archaius.Set("discovery.kind", "etcd")
- archaius.Set("registry.kind", "etcd")
- err := datasource.Init(datasource.Options{Config: etcdadpt.Config{Kind: "etcd"}})
- if err != nil {
- panic(err)
- }
-}
-func TestGetResourceLimit(t *testing.T) {
- //var id string
- ctx := context.TODO()
- ctx = util.SetDomainProject(ctx, "quota", "quota")
- t.Run("create service,should success", func(t *testing.T) {
- res := quota.NewApplyQuotaResource(quota.TypeService, "quota/quota", "", 1)
- err := quota.Apply(ctx, res)
- assert.Nil(t, err)
- })
- t.Run("create 1 instance,should success", func(t *testing.T) {
- resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
- Service: &pb.MicroService{
- ServiceName: "quota",
- },
- })
- assert.NoError(t, err)
- assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
-
- res := quota.NewApplyQuotaResource(quota.TypeInstance, "quota/quota", resp.ServiceId, 1)
- err = quota.Apply(ctx, res)
- assert.Nil(t, err)
-
- res = quota.NewApplyQuotaResource(quota.TypeInstance, "quota/quota", resp.ServiceId, 150001)
- err = quota.Apply(ctx, res)
- assert.NotNil(t, err)
- })
- t.Run("create 150001 instance,should failed", func(t *testing.T) {
- resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
- Service: &pb.MicroService{
- ServiceName: "quota2",
- },
- })
- assert.NoError(t, err)
- assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
-
- res := quota.NewApplyQuotaResource(quota.TypeInstance, "quota/quota", resp.ServiceId, 150001)
- err = quota.Apply(ctx, res)
- assert.NotNil(t, err)
- })
-
-}
diff --git a/server/plugin/quota/buildin/instance.go b/server/plugin/quota/buildin/instance.go
new file mode 100644
index 0000000..674310a
--- /dev/null
+++ b/server/plugin/quota/buildin/instance.go
@@ -0,0 +1,33 @@
+/*
+ * 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().GetInstanceCount(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
new file mode 100644
index 0000000..6352c59
--- /dev/null
+++ b/server/plugin/quota/buildin/instance_test.go
@@ -0,0 +1,66 @@
+/*
+ * 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
new file mode 100644
index 0000000..f771d14
--- /dev/null
+++ b/server/plugin/quota/buildin/role.go
@@ -0,0 +1,32 @@
+/*
+ * 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"
+)
+
+func RoleUsage(ctx context.Context) (int64, error) {
+ _, used, err := datasource.GetRoleManager().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
new file mode 100644
index 0000000..3a860bb
--- /dev/null
+++ b/server/plugin/quota/buildin/schema.go
@@ -0,0 +1,36 @@
+/*
+ * 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"
+ "github.com/go-chassis/cari/discovery"
+)
+
+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
+}
diff --git a/server/plugin/quota/buildin/service.go b/server/plugin/quota/buildin/service.go
new file mode 100644
index 0000000..159e029
--- /dev/null
+++ b/server/plugin/quota/buildin/service.go
@@ -0,0 +1,33 @@
+/*
+ * 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().GetServiceCount(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
new file mode 100644
index 0000000..11ffa66
--- /dev/null
+++ b/server/plugin/quota/buildin/service_test.go
@@ -0,0 +1,60 @@
+/*
+ * 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/plugin/quota/quota.go b/server/plugin/quota/quota.go
index 38865ca..e24601b 100644
--- a/server/plugin/quota/quota.go
+++ b/server/plugin/quota/quota.go
@@ -21,145 +21,52 @@
"context"
"errors"
"fmt"
- "strconv"
"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/service/quota"
pb "github.com/go-chassis/cari/discovery"
)
const QUOTA plugin.Kind = "quota"
-const (
- defaultServiceLimit = 50000
- defaultInstanceLimit = 150000
- defaultSchemaLimit = 100
- defaultTagLimit = 100
- defaultAccountLimit = 1000
- defaultRoleLimit = 100
-)
-
-const (
- TypeSchema ResourceType = iota
- TypeTag
- TypeService
- TypeInstance
- TypeAccount
- TypeRole
-)
-
-var (
- DefaultServiceQuota = defaultServiceLimit
- DefaultInstanceQuota = defaultInstanceLimit
- DefaultSchemaQuota = defaultSchemaLimit
- DefaultTagQuota = defaultTagLimit
- DefaultAccountQuota = defaultAccountLimit
- DefaultRoleQuota = defaultRoleLimit
-)
-
-func Init() {
- DefaultServiceQuota = config.GetInt("quota.cap.service.limit", defaultServiceLimit, config.WithENV("QUOTA_SERVICE"))
- DefaultInstanceQuota = config.GetInt("quota.cap.instance.limit", defaultInstanceLimit, config.WithENV("QUOTA_INSTANCE"))
- DefaultSchemaQuota = config.GetInt("quota.cap.schema.limit", defaultSchemaLimit, config.WithENV("QUOTA_SCHEMA"))
- DefaultTagQuota = config.GetInt("quota.cap.tag.limit", defaultTagLimit, config.WithENV("QUOTA_TAG"))
- DefaultAccountQuota = config.GetInt("quota.cap.account.limit", defaultAccountLimit, config.WithENV("QUOTA_ACCOUNT"))
- DefaultRoleQuota = config.GetInt("quota.cap.role.limit", defaultRoleLimit, config.WithENV("QUOTA_ROLE"))
-}
-
-type ApplyQuotaResource struct {
- QuotaType ResourceType
- DomainProject string
- ServiceID string
- QuotaSize int64
-}
-
-func NewApplyQuotaResource(quotaType ResourceType, domainProject, serviceID string, quotaSize int64) *ApplyQuotaResource {
- return &ApplyQuotaResource{
- quotaType,
- domainProject,
- serviceID,
- quotaSize,
- }
-}
-
type Manager interface {
- RemandQuotas(ctx context.Context, quotaType ResourceType)
+ RemandQuotas(ctx context.Context, t ResourceType)
GetQuota(ctx context.Context, t ResourceType) int64
+ Usage(ctx context.Context, req *Request) (int64, error)
}
-type ResourceType int
+func GetQuota(ctx context.Context, resourceType ResourceType) int64 {
+ return plugin.Plugins().Instance(QUOTA).(Manager).GetQuota(ctx, resourceType)
+}
-func (r ResourceType) String() string {
- switch r {
- case TypeSchema:
- return "SCHEMA"
- case TypeTag:
- return "TAG"
- case TypeService:
- return "SERVICE"
- case TypeInstance:
- return "INSTANCE"
- case TypeAccount:
- return "ACCOUNT"
- case TypeRole:
- return "ROLE"
- default:
- return "RESOURCE" + strconv.Itoa(int(r))
- }
+func Remand(ctx context.Context, resourceType ResourceType) {
+ plugin.Plugins().Instance(QUOTA).(Manager).RemandQuotas(ctx, resourceType)
+}
+
+func Usage(ctx context.Context, req *Request) (int64, error) {
+ return plugin.Plugins().Instance(QUOTA).(Manager).Usage(ctx, req)
}
// Apply 申请配额sourceType serviceinstance servicetype
-func Apply(ctx context.Context, res *ApplyQuotaResource) error {
+func Apply(ctx context.Context, res *Request) error {
if res == nil {
err := errors.New("invalid parameters")
log.Error("quota check failed", err)
return pb.NewError(pb.ErrInternal, err.Error())
}
- limitQuota := plugin.Plugins().Instance(QUOTA).(Manager).GetQuota(ctx, res.QuotaType)
- curNum, err := GetResourceUsage(ctx, res)
+ resourceType := res.QuotaType
+ limitQuota := GetQuota(ctx, resourceType)
+ curNum, err := Usage(ctx, res)
if err != nil {
- log.Error(fmt.Sprintf("%s quota check failed", res.QuotaType), err)
+ log.Error(fmt.Sprintf("%s quota check failed", resourceType), err)
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",
- res.QuotaType, limitQuota, curNum, res.QuotaSize)
+ resourceType, limitQuota, curNum, res.QuotaSize)
log.Error(mes, nil)
return pb.NewError(pb.ErrNotEnoughQuota, mes)
}
return nil
}
-
-func Remand(ctx context.Context, quotaType ResourceType) {
- plugin.Plugins().Instance(QUOTA).(Manager).RemandQuotas(ctx, quotaType)
-}
-func GetResourceUsage(ctx context.Context, res *ApplyQuotaResource) (int64, error) {
- serviceID := res.ServiceID
- switch res.QuotaType {
- case TypeService:
- return quota.ServiceUsage(ctx, &pb.GetServiceCountRequest{
- Domain: util.ParseDomain(ctx),
- Project: util.ParseProject(ctx),
- })
- case TypeInstance:
- return quota.InstanceUsage(ctx, &pb.GetServiceCountRequest{
- Domain: util.ParseDomain(ctx),
- Project: util.ParseProject(ctx),
- })
- case TypeSchema:
- return quota.SchemaUsage(ctx, serviceID)
- case TypeTag:
- // always re-create the service old tags
- return 0, nil
- case TypeRole:
- return quota.RoleUsage(ctx)
- case TypeAccount:
- return quota.AccountUsage(ctx)
- default:
- return 0, fmt.Errorf("not define quota type '%s'", res.QuotaType)
- }
-}
diff --git a/server/plugin/quota/request.go b/server/plugin/quota/request.go
new file mode 100644
index 0000000..93b56a2
--- /dev/null
+++ b/server/plugin/quota/request.go
@@ -0,0 +1,28 @@
+/*
+ * 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
+
+type ResourceType string
+
+type Request struct {
+ QuotaType ResourceType
+ Domain string
+ Project string
+ ServiceID string
+ QuotaSize int64
+}
diff --git a/server/service/disco/instance.go b/server/service/disco/instance.go
index 36ea884..4a57a9d 100644
--- a/server/service/disco/instance.go
+++ b/server/service/disco/instance.go
@@ -30,7 +30,7 @@
"github.com/apache/servicecomb-service-center/server/config"
apt "github.com/apache/servicecomb-service-center/server/core"
"github.com/apache/servicecomb-service-center/server/health"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/apache/servicecomb-service-center/server/service/validator"
pb "github.com/go-chassis/cari/discovery"
)
@@ -49,8 +49,7 @@
}, nil
}
remoteIP := util.GetIPFromContext(ctx)
- domainProject := util.ParseDomainProject(ctx)
- if quotaErr := checkInstanceQuota(ctx, domainProject, in.Instance.ServiceId); quotaErr != nil {
+ if quotaErr := checkInstanceQuota(ctx); quotaErr != nil {
log.Error(fmt.Sprintf("register instance failed, endpoints %v, host '%s', serviceID %s, operator %s",
in.Instance.Endpoints, in.Instance.HostName, in.Instance.ServiceId, remoteIP), quotaErr)
response, err := datasource.WrapErrResponse(quotaErr)
@@ -269,11 +268,9 @@
}, nil
}
-func checkInstanceQuota(ctx context.Context, domainProject string, serviceID string) error {
+func checkInstanceQuota(ctx context.Context) error {
if !apt.IsSCInstance(ctx) {
- res := quota.NewApplyQuotaResource(quota.TypeInstance,
- domainProject, serviceID, 1)
- return quota.Apply(ctx, res)
+ return quotasvc.ApplyInstance(ctx, 1)
}
return nil
}
diff --git a/server/service/disco/microservice.go b/server/service/disco/microservice.go
index 40215c3..f3735bf 100644
--- a/server/service/disco/microservice.go
+++ b/server/service/disco/microservice.go
@@ -25,7 +25,7 @@
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/core"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/apache/servicecomb-service-center/server/service/validator"
pb "github.com/go-chassis/cari/discovery"
"github.com/go-chassis/foundation/gopool"
@@ -61,8 +61,6 @@
service := in.Service
serviceFlag := util.StringJoin([]string{
service.Environment, service.AppId, service.ServiceName, service.Version}, "/")
- domainProject := util.ParseDomainProject(ctx)
-
datasource.SetServiceDefaultValue(service)
if err := validator.Validate(in); err != nil {
log.Error(fmt.Sprintf("create micro-service[%s] failed, operator: %s",
@@ -71,7 +69,7 @@
Response: pb.CreateResponse(pb.ErrInvalidParams, err.Error()),
}, nil
}
- if quotaErr := checkServiceQuota(ctx, domainProject); quotaErr != nil {
+ if quotaErr := checkServiceQuota(ctx); quotaErr != nil {
log.Error(fmt.Sprintf("create micro-service[%s] failed, operator: %s",
serviceFlag, remoteIP), quotaErr)
response, err := datasource.WrapErrResponse(quotaErr)
@@ -334,11 +332,10 @@
return true
}
-func checkServiceQuota(ctx context.Context, domainProject string) error {
+func checkServiceQuota(ctx context.Context) error {
if core.IsSCInstance(ctx) {
log.Debug("skip quota check")
return nil
}
- res := quota.NewApplyQuotaResource(quota.TypeService, domainProject, "", 1)
- return quota.Apply(ctx, res)
+ return quotasvc.ApplyService(ctx, 1)
}
diff --git a/server/service/disco/microservice_test.go b/server/service/disco/microservice_test.go
index 9230ffc..41f2b19 100644
--- a/server/service/disco/microservice_test.go
+++ b/server/service/disco/microservice_test.go
@@ -24,8 +24,8 @@
. "github.com/onsi/gomega"
"github.com/apache/servicecomb-service-center/server/core"
- "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"
pb "github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/pkg/errsvc"
)
@@ -55,7 +55,7 @@
Context("all max", func() {
It("should be passed", func() {
- size := quota.DefaultSchemaQuota + 1
+ size := int(quotasvc.SchemaQuota()) + 1
paths := make([]*pb.ServicePath, 0, size)
properties := make(map[string]string, size)
for i := 0; i < size; i++ {
diff --git a/server/service/disco/schema.go b/server/service/disco/schema.go
index a9275ae..3b3bc35 100644
--- a/server/service/disco/schema.go
+++ b/server/service/disco/schema.go
@@ -24,7 +24,7 @@
"github.com/apache/servicecomb-service-center/datasource"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/util"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/apache/servicecomb-service-center/server/service/validator"
pb "github.com/go-chassis/cari/discovery"
)
@@ -117,8 +117,7 @@
return pb.NewError(pb.ErrInvalidParams, err.Error())
}
- res := quota.NewApplyQuotaResource(quota.TypeSchema, domainProject, serviceID, 1)
- if errQuota := quota.Apply(ctx, res); errQuota != nil {
+ if errQuota := quotasvc.ApplySchema(ctx, serviceID, 1); errQuota != nil {
log.Error(fmt.Sprintf("update schema[%s/%s] failed, operator: %s", serviceID, schemaID, remoteIP), errQuota)
return errQuota
}
diff --git a/server/service/disco/schema_test.go b/server/service/disco/schema_test.go
index 5c64a8d..6e7f3f8 100644
--- a/server/service/disco/schema_test.go
+++ b/server/service/disco/schema_test.go
@@ -22,8 +22,8 @@
"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"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
pb "github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/pkg/errsvc"
"github.com/stretchr/testify/assert"
@@ -226,7 +226,8 @@
serviceIdDev = old
})
- size := quota.DefaultSchemaQuota + 1
+ max := int(quotasvc.SchemaQuota())
+ size := max + 1
schemaIds := make([]string, 0, size)
schemas := make([]*pb.Schema, 0, size)
for i := 0; i < size; i++ {
@@ -251,11 +252,11 @@
_, err = disco.PutSchemas(getContext(), &pb.ModifySchemasRequest{
ServiceId: serviceIdDev,
- Schemas: schemas[:quota.DefaultSchemaQuota],
+ Schemas: schemas[:max],
})
assert.NoError(t, err)
- schema := schemas[quota.DefaultSchemaQuota]
+ schema := schemas[max]
_, err = disco.PutSchema(getContext(), &pb.ModifySchemaRequest{
ServiceId: serviceIdDev,
SchemaId: schema.SchemaId,
diff --git a/server/service/disco/tag_test.go b/server/service/disco/tag_test.go
index 9b2193c..a789627 100644
--- a/server/service/disco/tag_test.go
+++ b/server/service/disco/tag_test.go
@@ -21,12 +21,12 @@
"strconv"
"strings"
- "github.com/apache/servicecomb-service-center/server/service/disco"
-
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
- pb "github.com/go-chassis/cari/discovery"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
+
+ "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"
)
var (
@@ -34,6 +34,8 @@
)
var _ = Describe("'Tag' service", func() {
+ max := int(quotasvc.TagQuota())
+
Describe("execute 'create' operation", func() {
var (
serviceId1 string
@@ -102,9 +104,8 @@
Context("when request is valid", func() {
It("should be passed", func() {
By("all max")
- size := quota.DefaultTagQuota
- tags := make(map[string]string, size)
- for i := 0; i < size; i++ {
+ tags := make(map[string]string, max)
+ for i := 0; i < max; i++ {
s := "tag" + strconv.Itoa(i)
tags[s] = s
}
@@ -128,7 +129,7 @@
Context("when create tag out of gauge", func() {
It("should be failed", func() {
- size := quota.DefaultTagQuota + 1
+ size := max + 1
tags := make(map[string]string, size)
for i := 0; i < size; i++ {
s := "tag" + strconv.Itoa(i)
@@ -141,9 +142,8 @@
Expect(err).To(BeNil())
Expect(respAddTags.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
- size = quota.DefaultTagQuota
- tags = make(map[string]string, size)
- for i := 0; i < size; i++ {
+ tags = make(map[string]string, max)
+ for i := 0; i < max; i++ {
s := "tag" + strconv.Itoa(i)
tags[s] = s
}
@@ -468,7 +468,7 @@
Expect(respAddTags.Response.GetCode()).To(Equal(pb.ErrInvalidParams))
var arr []string
- for i := 0; i < quota.DefaultTagQuota+1; i++ {
+ for i := 0; i < int(max)+1; i++ {
arr = append(arr, strconv.Itoa(i))
}
respAddTags, err = serviceResource.DeleteTags(getContext(), &pb.DeleteServiceTagsRequest{
diff --git a/server/service/quota/account.go b/server/service/quota/account.go
new file mode 100644
index 0000000..4244fc5
--- /dev/null
+++ b/server/service/quota/account.go
@@ -0,0 +1,36 @@
+/*
+ * 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/pkg/util"
+ "github.com/apache/servicecomb-service-center/server/plugin/quota"
+)
+
+const TypeAccount quota.ResourceType = "ACCOUNT"
+
+func ApplyAccount(ctx context.Context, size int64) error {
+ return quota.Apply(ctx, "a.Request{
+ QuotaType: TypeAccount,
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ QuotaSize: size,
+ })
+}
diff --git a/server/service/quota/instance.go b/server/service/quota/instance.go
new file mode 100644
index 0000000..a183216
--- /dev/null
+++ b/server/service/quota/instance.go
@@ -0,0 +1,44 @@
+/*
+ * 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/pkg/util"
+ "github.com/apache/servicecomb-service-center/server/plugin/quota"
+)
+
+const TypeInstance quota.ResourceType = "INSTANCE"
+
+func InstanceQuota() int64 {
+ return quota.GetQuota(context.Background(), TypeInstance)
+}
+
+func ApplyInstance(ctx context.Context, size int64) error {
+ return quota.Apply(ctx, "a.Request{
+ QuotaType: TypeInstance,
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ QuotaSize: size,
+ })
+}
+
+func RemandInstance(ctx context.Context) {
+ quota.Remand(ctx, TypeInstance)
+}
diff --git a/server/service/quota/instance_test.go b/server/service/quota/instance_test.go
new file mode 100644
index 0000000..6ce44da
--- /dev/null
+++ b/server/service/quota/instance_test.go
@@ -0,0 +1,71 @@
+/*
+ * 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_test
+
+import (
+ "context"
+ "testing"
+
+ _ "github.com/apache/servicecomb-service-center/test"
+
+ "github.com/apache/servicecomb-service-center/pkg/util"
+ discosvc "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"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestApplyInstance(t *testing.T) {
+ //var id string
+ ctx := context.TODO()
+ ctx = util.SetDomainProject(ctx, "quota", "quota")
+ t.Run("create 1 instance,should success", func(t *testing.T) {
+ resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
+ Service: &pb.MicroService{
+ ServiceName: "quota",
+ },
+ })
+ assert.NoError(t, err)
+ assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+ defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+ err = quotasvc.ApplyInstance(ctx, 1)
+ assert.Nil(t, err)
+
+ err = quotasvc.ApplyInstance(ctx, 150001)
+ assert.NotNil(t, err)
+ })
+
+ t.Run("create 150001 instance,should failed", func(t *testing.T) {
+ resp, err := discosvc.RegisterService(ctx, &pb.CreateServiceRequest{
+ Service: &pb.MicroService{
+ ServiceName: "quota2",
+ },
+ })
+ assert.NoError(t, err)
+ assert.Equal(t, pb.ResponseSuccess, resp.Response.GetCode())
+ defer discosvc.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: resp.ServiceId, Force: true})
+
+ err = quotasvc.ApplyInstance(ctx, 150001)
+ assert.NotNil(t, err)
+ })
+}
+
+func TestRemandInstance(t *testing.T) {
+ quotasvc.RemandInstance(context.Background())
+}
diff --git a/server/service/quota/quota.go b/server/service/quota/quota.go
deleted file mode 100644
index 036b0ff..0000000
--- a/server/service/quota/quota.go
+++ /dev/null
@@ -1,68 +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 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 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
-}
diff --git a/server/service/quota/quota_test.go b/server/service/quota/quota_test.go
deleted file mode 100644
index b709248..0000000
--- a/server/service/quota/quota_test.go
+++ /dev/null
@@ -1,103 +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 quota_test
-
-import (
- _ "github.com/apache/servicecomb-service-center/test"
-
- "context"
- "testing"
-
- "github.com/apache/servicecomb-service-center/pkg/util"
- "github.com/apache/servicecomb-service-center/server/service/disco"
- "github.com/apache/servicecomb-service-center/server/service/quota"
- pb "github.com/go-chassis/cari/discovery"
- "github.com/stretchr/testify/assert"
-)
-
-func getContext() context.Context {
- return util.WithNoCache(util.SetDomainProject(context.Background(), "default", "default"))
-}
-
-func TestServiceUsage(t *testing.T) {
- t.Run("get domain/project without service usage, should return 0", func(t *testing.T) {
- usage, err := quota.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")
- service, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
- Service: &pb.MicroService{
- ServiceName: "test",
- },
- })
- assert.NoError(t, err)
-
- usage, err := quota.ServiceUsage(context.Background(), &pb.GetServiceCountRequest{
- Domain: "domain_with_service",
- Project: "project_with_service",
- })
- assert.NoError(t, err)
- assert.Equal(t, int64(1), usage)
-
- _, err = disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: service.ServiceId})
- assert.NoError(t, err)
- })
-}
-
-func TestInstanceUsage(t *testing.T) {
- t.Run("get domain/project without instance usage, should return 0", func(t *testing.T) {
- usage, err := quota.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")
- service, err := disco.RegisterService(ctx, &pb.CreateServiceRequest{
- Service: &pb.MicroService{
- ServiceName: "test",
- },
- })
- assert.NoError(t, err)
-
- _, err = disco.RegisterInstance(ctx, &pb.RegisterInstanceRequest{Instance: &pb.MicroServiceInstance{
- ServiceId: service.ServiceId,
- HostName: "test",
- }})
- assert.NoError(t, err)
-
- usage, err := quota.InstanceUsage(context.Background(), &pb.GetServiceCountRequest{
- Domain: "domain_with_service",
- Project: "project_with_service",
- })
- assert.NoError(t, err)
- assert.Equal(t, int64(1), usage)
-
- _, err = disco.UnregisterService(ctx, &pb.DeleteServiceRequest{ServiceId: service.ServiceId, Force: true})
- assert.NoError(t, err)
- })
-}
diff --git a/server/service/quota/role.go b/server/service/quota/role.go
new file mode 100644
index 0000000..178a377
--- /dev/null
+++ b/server/service/quota/role.go
@@ -0,0 +1,36 @@
+/*
+ * 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/pkg/util"
+ "github.com/apache/servicecomb-service-center/server/plugin/quota"
+)
+
+const TypeRole quota.ResourceType = "ROLE"
+
+func ApplyRole(ctx context.Context, size int64) error {
+ return quota.Apply(ctx, "a.Request{
+ QuotaType: TypeRole,
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ QuotaSize: size,
+ })
+}
diff --git a/server/service/quota/schema.go b/server/service/quota/schema.go
new file mode 100644
index 0000000..fe2c21d
--- /dev/null
+++ b/server/service/quota/schema.go
@@ -0,0 +1,41 @@
+/*
+ * 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/pkg/util"
+ "github.com/apache/servicecomb-service-center/server/plugin/quota"
+)
+
+const TypeSchema quota.ResourceType = "SCHEMA"
+
+func SchemaQuota() int64 {
+ return quota.GetQuota(context.Background(), TypeSchema)
+}
+
+func ApplySchema(ctx context.Context, serviceID string, size int64) error {
+ return quota.Apply(ctx, "a.Request{
+ QuotaType: TypeSchema,
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ ServiceID: serviceID,
+ QuotaSize: size,
+ })
+}
diff --git a/server/service/quota/service.go b/server/service/quota/service.go
new file mode 100644
index 0000000..bedf589
--- /dev/null
+++ b/server/service/quota/service.go
@@ -0,0 +1,44 @@
+/*
+ * 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/pkg/util"
+ "github.com/apache/servicecomb-service-center/server/plugin/quota"
+)
+
+const TypeService quota.ResourceType = "SERVICE"
+
+func ServiceQuota() int64 {
+ return quota.GetQuota(context.Background(), TypeService)
+}
+
+func ApplyService(ctx context.Context, size int64) error {
+ return quota.Apply(ctx, "a.Request{
+ QuotaType: TypeService,
+ Domain: util.ParseDomain(ctx),
+ Project: util.ParseProject(ctx),
+ QuotaSize: size,
+ })
+}
+
+func RemandService(ctx context.Context) {
+ quota.Remand(ctx, TypeService)
+}
diff --git a/server/service/quota/service_test.go b/server/service/quota/service_test.go
new file mode 100644
index 0000000..2a3884b
--- /dev/null
+++ b/server/service/quota/service_test.go
@@ -0,0 +1,43 @@
+/*
+ * 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_test
+
+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/stretchr/testify/assert"
+)
+
+func TestApplyService(t *testing.T) {
+ //var id string
+ ctx := context.TODO()
+ ctx = util.SetDomainProject(ctx, "quota", "quota")
+ t.Run("create service, should success", func(t *testing.T) {
+ err := quotasvc.ApplyService(ctx, 1)
+ assert.Nil(t, err)
+ })
+}
+
+func TestRemandService(t *testing.T) {
+ quotasvc.RemandService(context.Background())
+}
diff --git a/server/service/quota/tag.go b/server/service/quota/tag.go
new file mode 100644
index 0000000..e846269
--- /dev/null
+++ b/server/service/quota/tag.go
@@ -0,0 +1,30 @@
+/*
+ * 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/server/plugin/quota"
+)
+
+const TypeTag quota.ResourceType = "TAG"
+
+func TagQuota() int64 {
+ return quota.GetQuota(context.Background(), TypeTag)
+}
diff --git a/server/service/rbac/account_service.go b/server/service/rbac/account_service.go
index 464c011..f893f37 100644
--- a/server/service/rbac/account_service.go
+++ b/server/service/rbac/account_service.go
@@ -25,8 +25,7 @@
"github.com/apache/servicecomb-service-center/datasource"
errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
"github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/pkg/util"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/apache/servicecomb-service-center/server/service/validator"
"github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/rbac"
@@ -34,8 +33,7 @@
//CreateAccount save account info
func CreateAccount(ctx context.Context, a *rbac.Account) error {
- quotaErr := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeAccount,
- util.ParseDomainProject(ctx), "", 1))
+ quotaErr := quotasvc.ApplyAccount(ctx, 1)
if quotaErr != nil {
return rbac.NewError(rbac.ErrAccountNoQuota, quotaErr.Error())
}
diff --git a/server/service/rbac/role_service.go b/server/service/rbac/role_service.go
index 7a76710..a317596 100644
--- a/server/service/rbac/role_service.go
+++ b/server/service/rbac/role_service.go
@@ -22,14 +22,13 @@
"errors"
"fmt"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/go-chassis/cari/discovery"
"github.com/go-chassis/cari/rbac"
"github.com/apache/servicecomb-service-center/datasource"
errorsEx "github.com/apache/servicecomb-service-center/pkg/errors"
"github.com/apache/servicecomb-service-center/pkg/log"
- "github.com/apache/servicecomb-service-center/pkg/util"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
"github.com/apache/servicecomb-service-center/server/service/validator"
)
@@ -39,8 +38,7 @@
log.Error(fmt.Sprintf("create role [%s] failed", r.Name), err)
return discovery.NewError(discovery.ErrInvalidParams, err.Error())
}
- quotaErr := quota.Apply(ctx, quota.NewApplyQuotaResource(quota.TypeRole,
- util.ParseDomainProject(ctx), "", 1))
+ quotaErr := quotasvc.ApplyRole(ctx, 1)
if quotaErr != nil {
return rbac.NewError(rbac.ErrRoleNoQuota, quotaErr.Error())
}
diff --git a/server/service/validator/microservice_validator.go b/server/service/validator/microservice_validator.go
index 486721f..d1201ce 100644
--- a/server/service/validator/microservice_validator.go
+++ b/server/service/validator/microservice_validator.go
@@ -22,7 +22,7 @@
"github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/pkg/validate"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
"github.com/go-chassis/cari/discovery"
)
@@ -88,6 +88,8 @@
func CreateServiceReqValidator() *validate.Validator {
return createServiceReqValidator.Init(func(v *validate.Validator) {
+ max := int(quotasvc.SchemaQuota())
+
var pathValidator validate.Validator
pathValidator.AddRule("Path", &validate.Rule{Regexp: pathRegex})
@@ -103,7 +105,7 @@
microServiceValidator.AddRule("Description", &validate.Rule{Max: 256})
microServiceValidator.AddRule("Level", &validate.Rule{Regexp: levelRegex})
microServiceValidator.AddRule("Status", &validate.Rule{Regexp: statusRegex})
- microServiceValidator.AddRule("Schemas", &validate.Rule{Max: quota.DefaultSchemaQuota, Regexp: schemaIDRegex})
+ microServiceValidator.AddRule("Schemas", &validate.Rule{Max: max, Regexp: schemaIDRegex})
microServiceValidator.AddSub("Paths", &pathValidator)
microServiceValidator.AddRule("Alias", &validate.Rule{Max: 128, Regexp: aliasRegex})
microServiceValidator.AddRule("RegisterBy", &validate.Rule{Max: 64, Regexp: registerByRegex})
diff --git a/server/service/validator/schema_validator.go b/server/service/validator/schema_validator.go
index 7cecff5..077294e 100644
--- a/server/service/validator/schema_validator.go
+++ b/server/service/validator/schema_validator.go
@@ -21,7 +21,7 @@
"regexp"
"github.com/apache/servicecomb-service-center/pkg/validate"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
)
var (
@@ -44,13 +44,15 @@
func ModifySchemasReqValidator() *validate.Validator {
return modifySchemasReqValidator.Init(func(v *validate.Validator) {
+ max := int(quotasvc.SchemaQuota())
+
var subSchemaValidator validate.Validator
subSchemaValidator.AddRule("SchemaId", GetSchemaReqValidator().GetRule("SchemaId"))
subSchemaValidator.AddRule("Summary", &validate.Rule{Min: 1, Max: 128, Regexp: schemaSummaryRegex})
subSchemaValidator.AddRule("Schema", &validate.Rule{Min: 1})
v.AddRule("ServiceId", GetServiceReqValidator().GetRule("ServiceId"))
- v.AddRule("Schemas", &validate.Rule{Min: 1, Max: quota.DefaultSchemaQuota})
+ v.AddRule("Schemas", &validate.Rule{Min: 1, Max: max})
v.AddSub("Schemas", &subSchemaValidator)
})
}
diff --git a/server/service/validator/tag_validator.go b/server/service/validator/tag_validator.go
index bdd00af..8f0f299 100644
--- a/server/service/validator/tag_validator.go
+++ b/server/service/validator/tag_validator.go
@@ -21,7 +21,7 @@
"regexp"
"github.com/apache/servicecomb-service-center/pkg/validate"
- "github.com/apache/servicecomb-service-center/server/plugin/quota"
+ quotasvc "github.com/apache/servicecomb-service-center/server/service/quota"
)
var (
@@ -43,8 +43,9 @@
func AddTagsReqValidator() *validate.Validator {
return addTagsReqValidator.Init(func(v *validate.Validator) {
+ max := int(quotasvc.TagQuota())
v.AddRule("ServiceId", GetServiceReqValidator().GetRule("ServiceId"))
- v.AddRule("Tags", &validate.Rule{Max: quota.DefaultTagQuota, Regexp: tagRegex})
+ v.AddRule("Tags", &validate.Rule{Max: max, Regexp: tagRegex})
})
}
@@ -59,7 +60,8 @@
func DeleteTagReqValidator() *validate.Validator {
return deleteTagReqValidator.Init(func(v *validate.Validator) {
+ max := int(quotasvc.TagQuota())
v.AddRule("ServiceId", GetServiceReqValidator().GetRule("ServiceId"))
- v.AddRule("Keys", &validate.Rule{Min: 1, Max: quota.DefaultTagQuota, Regexp: tagRegex})
+ v.AddRule("Keys", &validate.Rule{Min: 1, Max: max, Regexp: tagRegex})
})
}
diff --git a/test/test.go b/test/test.go
index d5d651e..d1c4c2f 100644
--- a/test/test.go
+++ b/test/test.go
@@ -23,7 +23,6 @@
"os"
"path/filepath"
- "github.com/apache/servicecomb-service-center/pkg/util"
_ "github.com/apache/servicecomb-service-center/server/init"
_ "github.com/apache/servicecomb-service-center/server/bootstrap"
@@ -31,6 +30,7 @@
_ "github.com/go-chassis/go-chassis-extension/protocol/grpc/server"
"github.com/apache/servicecomb-service-center/datasource"
+ "github.com/apache/servicecomb-service-center/pkg/util"
"github.com/apache/servicecomb-service-center/server/core"
"github.com/apache/servicecomb-service-center/server/metrics"
"github.com/apache/servicecomb-service-center/server/service/disco"