From 16c5a857ec37c5798e74e5d7353c7f7ebdc69ba5 Mon Sep 17 00:00:00 2001 From: Pubudu Gunatilaka Date: Tue, 17 Oct 2023 15:43:13 +0530 Subject: [PATCH] Adding resource level rate limit support for sandbox routes --- .../oasparser/envoyconf/internal_dtos.go | 2 + .../oasparser/envoyconf/routes_configs.go | 8 +- .../envoyconf/routes_with_clusters.go | 2 + common-controller/internal/cache/datastore.go | 14 +- .../controller/ratelimitpolicy_controller.go | 194 +++++++++--------- common-controller/internal/xds/server.go | 43 ++-- .../artifacts/apk-confs/simple_rl_conf.yaml | 2 + .../apk-confs/simple_rl_resource_conf.yaml | 2 + .../tests/api/SimpleRateLimit.feature | 8 + 9 files changed, 151 insertions(+), 124 deletions(-) diff --git a/adapter/internal/oasparser/envoyconf/internal_dtos.go b/adapter/internal/oasparser/envoyconf/internal_dtos.go index 7c8248fb70..fd4242b277 100644 --- a/adapter/internal/oasparser/envoyconf/internal_dtos.go +++ b/adapter/internal/oasparser/envoyconf/internal_dtos.go @@ -44,6 +44,7 @@ type routeCreateParams struct { apiLevelRateLimitPolicy *model.RateLimitPolicy apiProperties []dpv1alpha1.Property environment string + envType string } // RatelimitCriteria criterias of rate limiting @@ -52,4 +53,5 @@ type ratelimitCriteria struct { organizationID string basePathForRLService string environment string + envType string } diff --git a/adapter/internal/oasparser/envoyconf/routes_configs.go b/adapter/internal/oasparser/envoyconf/routes_configs.go index ac27af9a87..20e54fc36f 100644 --- a/adapter/internal/oasparser/envoyconf/routes_configs.go +++ b/adapter/internal/oasparser/envoyconf/routes_configs.go @@ -34,6 +34,7 @@ import ( logger "github.com/wso2/apk/adapter/internal/loggers" "github.com/wso2/apk/adapter/internal/oasparser/constants" "github.com/wso2/apk/adapter/internal/oasparser/model" + opConstants "github.com/wso2/apk/adapter/internal/operator/constants" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/wrapperspb" @@ -112,6 +113,11 @@ func generateRouteAction(apiType string, routeConfig *model.EndpointConfig, rate func generateRateLimitPolicy(ratelimitCriteria *ratelimitCriteria) []*routev3.RateLimit { + environmentValue := ratelimitCriteria.environment + if ratelimitCriteria.level != RateLimitPolicyAPILevel && ratelimitCriteria.envType == opConstants.Sandbox { + environmentValue += "_sandbox" + } + rateLimit := routev3.RateLimit{ Actions: []*routev3.RateLimit_Action{ { @@ -126,7 +132,7 @@ func generateRateLimitPolicy(ratelimitCriteria *ratelimitCriteria) []*routev3.Ra ActionSpecifier: &routev3.RateLimit_Action_GenericKey_{ GenericKey: &routev3.RateLimit_Action_GenericKey{ DescriptorKey: DescriptorKeyForEnvironment, - DescriptorValue: ratelimitCriteria.environment, + DescriptorValue: environmentValue, }, }, }, diff --git a/adapter/internal/oasparser/envoyconf/routes_with_clusters.go b/adapter/internal/oasparser/envoyconf/routes_with_clusters.go index da527f3587..1792b31812 100644 --- a/adapter/internal/oasparser/envoyconf/routes_with_clusters.go +++ b/adapter/internal/oasparser/envoyconf/routes_with_clusters.go @@ -818,6 +818,7 @@ func createRoutes(params *routeCreateParams) (routes []*routev3.Route, err error organizationID: params.organizationID, basePathForRLService: basePathForRLService, environment: params.environment, + envType: params.envType, } } var ( @@ -1529,6 +1530,7 @@ func genRouteCreateParams(swagger *model.AdapterInternalAPI, resource *model.Res routeConfig: resource.GetEndpoints().Config, createDefaultPath: createDefaultPath, environment: swagger.GetEnvironment(), + envType: swagger.EnvType, } return params } diff --git a/common-controller/internal/cache/datastore.go b/common-controller/internal/cache/datastore.go index 0a05be97a7..528dfdd2d1 100644 --- a/common-controller/internal/cache/datastore.go +++ b/common-controller/internal/cache/datastore.go @@ -28,7 +28,7 @@ import ( // RatelimitDataStore is a cache for rate limit policies. type RatelimitDataStore struct { - resolveRatelimitStore map[types.NamespacedName]*dpv1alpha1.ResolveRateLimitAPIPolicy + resolveRatelimitStore map[types.NamespacedName][]dpv1alpha1.ResolveRateLimitAPIPolicy customRatelimitStore map[types.NamespacedName]*dpv1alpha1.CustomRateLimitPolicyDef mu sync.Mutex } @@ -36,18 +36,18 @@ type RatelimitDataStore struct { // CreateNewOperatorDataStore creates a new RatelimitDataStore. func CreateNewOperatorDataStore() *RatelimitDataStore { return &RatelimitDataStore{ - resolveRatelimitStore: map[types.NamespacedName]*dpv1alpha1.ResolveRateLimitAPIPolicy{}, + resolveRatelimitStore: map[types.NamespacedName][]dpv1alpha1.ResolveRateLimitAPIPolicy{}, customRatelimitStore: map[types.NamespacedName]*dpv1alpha1.CustomRateLimitPolicyDef{}, } } // AddorUpdateResolveRatelimitToStore adds a new ratelimit to the RatelimitDataStore. func (ods *RatelimitDataStore) AddorUpdateResolveRatelimitToStore(rateLimit types.NamespacedName, - resolveRatelimit dpv1alpha1.ResolveRateLimitAPIPolicy) { + resolveRatelimitPolicyList []dpv1alpha1.ResolveRateLimitAPIPolicy) { ods.mu.Lock() defer ods.mu.Unlock() logger.Debug("Adding/Updating ratelimit to cache") - ods.resolveRatelimitStore[rateLimit] = &resolveRatelimit + ods.resolveRatelimitStore[rateLimit] = resolveRatelimitPolicyList } // AddorUpdateCustomRatelimitToStore adds a new ratelimit to the RatelimitDataStore. @@ -60,11 +60,11 @@ func (ods *RatelimitDataStore) AddorUpdateCustomRatelimitToStore(rateLimit types } // GetResolveRatelimitPolicy get cached ratelimit -func (ods *RatelimitDataStore) GetResolveRatelimitPolicy(rateLimit types.NamespacedName) (dpv1alpha1.ResolveRateLimitAPIPolicy, bool) { - var rateLimitPolicy dpv1alpha1.ResolveRateLimitAPIPolicy +func (ods *RatelimitDataStore) GetResolveRatelimitPolicy(rateLimit types.NamespacedName) ([]dpv1alpha1.ResolveRateLimitAPIPolicy, bool) { + var rateLimitPolicy []dpv1alpha1.ResolveRateLimitAPIPolicy if cachedRatelimit, found := ods.resolveRatelimitStore[rateLimit]; found { logger.Debug("Found cached ratelimit") - return *cachedRatelimit, true + return cachedRatelimit, true } return rateLimitPolicy, false } diff --git a/common-controller/internal/operator/controller/ratelimitpolicy_controller.go b/common-controller/internal/operator/controller/ratelimitpolicy_controller.go index 7bc8b6b695..0205fa9796 100644 --- a/common-controller/internal/operator/controller/ratelimitpolicy_controller.go +++ b/common-controller/internal/operator/controller/ratelimitpolicy_controller.go @@ -134,14 +134,12 @@ func (ratelimitReconsiler *RateLimitPolicyReconciler) Reconcile(ctx context.Cont // Check k8s RatelimitPolicy Availbility if err := ratelimitReconsiler.client.Get(ctx, ratelimitKey, &ratelimitPolicy); err != nil { - resolveRateLimitAPIPolicy, found := ratelimitReconsiler.ods.GetResolveRatelimitPolicy(req.NamespacedName) + resolveRateLimitAPIPolicyList, found := ratelimitReconsiler.ods.GetResolveRatelimitPolicy(req.NamespacedName) // If availble in cache Delete cache and xds if found && k8error.IsNotFound(err) { ratelimitReconsiler.ods.DeleteResolveRatelimitPolicy(req.NamespacedName) - xds.DeleteAPILevelRateLimitPolicies(resolveRateLimitAPIPolicy) - if resolveRateLimitAPIPolicy.Resources != nil { - xds.DeleteResourceLevelRateLimitPolicies(resolveRateLimitAPIPolicy) - } + xds.DeleteAPILevelRateLimitPolicies(resolveRateLimitAPIPolicyList) + xds.DeleteResourceLevelRateLimitPolicies(resolveRateLimitAPIPolicyList) xds.UpdateRateLimiterPolicies(conf.CommonController.Server.Label) } resolveCustomRateLimitPolicy, foundCustom := ratelimitReconsiler.ods.GetCachedCustomRatelimitPolicy(req.NamespacedName) @@ -160,11 +158,11 @@ func (ratelimitReconsiler *RateLimitPolicyReconciler) Reconcile(ctx context.Cont xds.UpdateRateLimitXDSCacheForCustomPolicies(customRateLimitPolicy) } else { - if resolveRatelimit, err := ratelimitReconsiler.marshelRateLimit(ctx, ratelimitKey, ratelimitPolicy); err != nil { + if resolveRatelimitPolicyList, err := ratelimitReconsiler.marshelRateLimit(ctx, ratelimitKey, ratelimitPolicy); err != nil { return ctrl.Result{}, err - } else if resolveRatelimit != nil { - ratelimitReconsiler.ods.AddorUpdateResolveRatelimitToStore(ratelimitKey, *resolveRatelimit) - xds.UpdateRateLimitXDSCache(*resolveRatelimit) + } else if len(resolveRatelimitPolicyList) > 0 { + ratelimitReconsiler.ods.AddorUpdateResolveRatelimitToStore(ratelimitKey, resolveRatelimitPolicyList) + xds.UpdateRateLimitXDSCache(resolveRatelimitPolicyList) xds.UpdateRateLimiterPolicies(conf.CommonController.Server.Label) } } @@ -239,21 +237,26 @@ func (ratelimitReconsiler *RateLimitPolicyReconciler) getRatelimitForHTTPRoute(c } func (ratelimitReconsiler *RateLimitPolicyReconciler) marshelRateLimit(ctx context.Context, ratelimitKey types.NamespacedName, - ratelimitPolicy dpv1alpha1.RateLimitPolicy) (*dpv1alpha1.ResolveRateLimitAPIPolicy, error) { + ratelimitPolicy dpv1alpha1.RateLimitPolicy) ([]dpv1alpha1.ResolveRateLimitAPIPolicy, error) { + + policyList := []dpv1alpha1.ResolveRateLimitAPIPolicy{} var api dpv1alpha1.API - var resolveResourceList []dpv1alpha1.ResolveResource - var resolveRatelimit dpv1alpha1.ResolveRateLimitAPIPolicy + + if err := ratelimitReconsiler.client.Get(ctx, types.NamespacedName{ + Namespace: ratelimitKey.Namespace, + Name: string(ratelimitPolicy.Spec.TargetRef.Name)}, + &api); err != nil { + return nil, fmt.Errorf("error while getting API : %v, %s", string(ratelimitPolicy.Spec.TargetRef.Name), err.Error()) + } + + organization := api.Spec.Organization + basePath := api.Spec.BasePath + environment := utils.GetEnvironment(api.Spec.Environment) + // API Level Rate limit policy if ratelimitPolicy.Spec.TargetRef.Kind == constants.KindAPI { - if err := ratelimitReconsiler.client.Get(ctx, types.NamespacedName{ - Namespace: ratelimitKey.Namespace, - Name: string(ratelimitPolicy.Spec.TargetRef.Name)}, - &api); err != nil { - return nil, fmt.Errorf("error while getting API : %v, %s", string(ratelimitPolicy.Spec.TargetRef.Name), err.Error()) - } - var organization = api.Spec.Organization - var basePath = api.Spec.BasePath + var resolveRatelimit dpv1alpha1.ResolveRateLimitAPIPolicy if ratelimitPolicy.Spec.Override != nil { resolveRatelimit.API.RequestsPerUnit = ratelimitPolicy.Spec.Override.API.RequestsPerUnit resolveRatelimit.API.Unit = ratelimitPolicy.Spec.Override.API.Unit @@ -262,106 +265,95 @@ func (ratelimitReconsiler *RateLimitPolicyReconciler) marshelRateLimit(ctx conte resolveRatelimit.API.Unit = ratelimitPolicy.Spec.Default.API.Unit } - resolveRatelimit.Environment = utils.GetEnvironment(api.Spec.Environment) + resolveRatelimit.Environment = environment resolveRatelimit.Organization = organization resolveRatelimit.BasePath = basePath resolveRatelimit.UUID = string(api.ObjectMeta.UID) + policyList = append(policyList, resolveRatelimit) } // Resource Level Rate limit policy if ratelimitPolicy.Spec.TargetRef.Kind == constants.KindResource { - if err := ratelimitReconsiler.client.Get(ctx, types.NamespacedName{ - Namespace: ratelimitKey.Namespace, - Name: string(ratelimitPolicy.Spec.TargetRef.Name)}, - &api); err != nil { - return nil, fmt.Errorf("error while getting API : %v, %s", string(ratelimitPolicy.Spec.TargetRef.Name), err.Error()) - } - var organization = api.Spec.Organization - var basePath = api.Spec.BasePath - var httpRoute gwapiv1b1.HTTPRoute + + var resolveRatelimit dpv1alpha1.ResolveRateLimitAPIPolicy + resolveRatelimit.Organization = organization + resolveRatelimit.BasePath = basePath + resolveRatelimit.UUID = string(api.ObjectMeta.UID) + resolveRatelimit.Environment = environment + if len(api.Spec.Production) > 0 { - for _, ref := range api.Spec.Production[0].HTTPRouteRefs { - if ref != "" { - if err := ratelimitReconsiler.client.Get(ctx, types.NamespacedName{ - Namespace: ratelimitKey.Namespace, - Name: ref}, - &httpRoute); err != nil { - return nil, fmt.Errorf("error while getting HTTPRoute : %v for API : %v, %s", string(ref), - string(ratelimitPolicy.Spec.TargetRef.Name), err.Error()) - } - for _, rule := range httpRoute.Spec.Rules { - for _, filter := range rule.Filters { - if filter.ExtensionRef != nil { - if filter.ExtensionRef.Kind == constants.KindRateLimitPolicy && string(filter.ExtensionRef.Name) == ratelimitPolicy.Name { - var resolveResource dpv1alpha1.ResolveResource - resolveResource.Path = *rule.Matches[0].Path.Value - if rule.Matches[0].Method != nil { - resolveResource.Method = string(*rule.Matches[0].Method) - } else { - resolveResource.Method = constants.All - } - resolveResource.PathMatchType = *rule.Matches[0].Path.Type - if ratelimitPolicy.Spec.Override != nil { - resolveResource.ResourceRatelimit.RequestsPerUnit = ratelimitPolicy.Spec.Override.API.RequestsPerUnit - resolveResource.ResourceRatelimit.Unit = ratelimitPolicy.Spec.Override.API.Unit - } else { - resolveResource.ResourceRatelimit.RequestsPerUnit = ratelimitPolicy.Spec.Default.API.RequestsPerUnit - resolveResource.ResourceRatelimit.Unit = ratelimitPolicy.Spec.Default.API.Unit - } - resolveResourceList = append(resolveResourceList, resolveResource) - } - } - } - } - } + resolveResourceList, err := ratelimitReconsiler.getResourceList(ctx, ratelimitKey, ratelimitPolicy, api.Spec.Production[0].HTTPRouteRefs) + if err != nil { + return nil, err + } + if len(resolveResourceList) > 0 { + resolveRatelimit.Resources = resolveResourceList + policyList = append(policyList, resolveRatelimit) } } + if len(api.Spec.Sandbox) > 0 { - for _, ref := range api.Spec.Sandbox[0].HTTPRouteRefs { - if ref != "" { - if err := ratelimitReconsiler.client.Get(ctx, types.NamespacedName{ - Namespace: ratelimitKey.Namespace, - Name: ref}, - &httpRoute); err != nil { - return nil, fmt.Errorf("error while getting HTTPRoute : %v for API : %v, %s", string(ref), - string(ratelimitPolicy.Spec.TargetRef.Name), err.Error()) - } - for _, rule := range httpRoute.Spec.Rules { - for _, filter := range rule.Filters { - if filter.ExtensionRef != nil { - if filter.ExtensionRef.Kind == constants.KindRateLimitPolicy && string(filter.ExtensionRef.Name) == ratelimitPolicy.Name { - var resolveResource dpv1alpha1.ResolveResource - resolveResource.Path = *rule.Matches[0].Path.Value - if rule.Matches[0].Method != nil { - resolveResource.Method = string(*rule.Matches[0].Method) - } else { - resolveResource.Method = constants.All - } - resolveResource.PathMatchType = *rule.Matches[0].Path.Type - if ratelimitPolicy.Spec.Override != nil { - resolveResource.ResourceRatelimit.RequestsPerUnit = ratelimitPolicy.Spec.Override.API.RequestsPerUnit - resolveResource.ResourceRatelimit.Unit = ratelimitPolicy.Spec.Override.API.Unit - } else { - resolveResource.ResourceRatelimit.RequestsPerUnit = ratelimitPolicy.Spec.Default.API.RequestsPerUnit - resolveResource.ResourceRatelimit.Unit = ratelimitPolicy.Spec.Default.API.Unit - } - resolveResourceList = append(resolveResourceList, resolveResource) - } + + resolveResourceList, err := ratelimitReconsiler.getResourceList(ctx, ratelimitKey, ratelimitPolicy, api.Spec.Sandbox[0].HTTPRouteRefs) + if err != nil { + return nil, err + } + if len(resolveResourceList) > 0 { + resolveRatelimit.Resources = resolveResourceList + resolveRatelimit.Environment += "_sandbox" + policyList = append(policyList, resolveRatelimit) + } + } + } + + return policyList, nil +} + +func (ratelimitReconsiler *RateLimitPolicyReconciler) getResourceList(ctx context.Context, ratelimitKey types.NamespacedName, + ratelimitPolicy dpv1alpha1.RateLimitPolicy, httpRefs []string) ([]dpv1alpha1.ResolveResource, error) { + + var resolveResourceList []dpv1alpha1.ResolveResource + var httpRoute gwapiv1b1.HTTPRoute + + for _, ref := range httpRefs { + if ref != "" { + if err := ratelimitReconsiler.client.Get(ctx, types.NamespacedName{ + Namespace: ratelimitKey.Namespace, + Name: ref}, + &httpRoute); err != nil { + return nil, fmt.Errorf("error while getting HTTPRoute : %v for API : %v, %s", string(ref), + string(ratelimitPolicy.Spec.TargetRef.Name), err.Error()) + } + for _, rule := range httpRoute.Spec.Rules { + for _, filter := range rule.Filters { + if filter.ExtensionRef != nil { + if filter.ExtensionRef.Kind == constants.KindRateLimitPolicy && string(filter.ExtensionRef.Name) == ratelimitPolicy.Name { + var resolveResource dpv1alpha1.ResolveResource + resolveResource.Path = *rule.Matches[0].Path.Value + if rule.Matches[0].Method != nil { + resolveResource.Method = string(*rule.Matches[0].Method) + } else { + resolveResource.Method = constants.All } + resolveResource.PathMatchType = *rule.Matches[0].Path.Type + if ratelimitPolicy.Spec.Override != nil { + resolveResource.ResourceRatelimit.RequestsPerUnit = ratelimitPolicy.Spec.Override.API.RequestsPerUnit + resolveResource.ResourceRatelimit.Unit = ratelimitPolicy.Spec.Override.API.Unit + } else { + resolveResource.ResourceRatelimit.RequestsPerUnit = ratelimitPolicy.Spec.Default.API.RequestsPerUnit + resolveResource.ResourceRatelimit.Unit = ratelimitPolicy.Spec.Default.API.Unit + } + resolveResourceList = append(resolveResourceList, resolveResource) } - } } + } } - resolveRatelimit.Organization = organization - resolveRatelimit.BasePath = basePath - resolveRatelimit.UUID = string(api.ObjectMeta.UID) - resolveRatelimit.Environment = utils.GetEnvironment(api.Spec.Environment) - resolveRatelimit.Resources = resolveResourceList } - return &resolveRatelimit, nil + + return resolveResourceList, nil } func (ratelimitReconsiler *RateLimitPolicyReconciler) marshelCustomRateLimit(ctx context.Context, ratelimitKey types.NamespacedName, diff --git a/common-controller/internal/xds/server.go b/common-controller/internal/xds/server.go index 7a3782043d..5ed7d9960c 100644 --- a/common-controller/internal/xds/server.go +++ b/common-controller/internal/xds/server.go @@ -55,9 +55,12 @@ func GetRateLimiterCache() envoy_cachev3.SnapshotCache { } // UpdateRateLimitXDSCache updates the xDS cache of the RateLimiter. -func UpdateRateLimitXDSCache(resolveRatelimit dpv1alpha1.ResolveRateLimitAPIPolicy) { - // Add Rate Limit inline policies in API to the cache - rlsPolicyCache.AddAPILevelRateLimitPolicies(resolveRatelimit) +func UpdateRateLimitXDSCache(resolveRatelimitPolicyList []dpv1alpha1.ResolveRateLimitAPIPolicy) { + + for _, resolveRatelimitPolicy := range resolveRatelimitPolicyList { + // Add Rate Limit inline policies in API to the cache + rlsPolicyCache.AddAPILevelRateLimitPolicies(resolveRatelimitPolicy) + } } // UpdateRateLimitXDSCacheForCustomPolicies updates the xDS cache of the RateLimiter for custom policies. @@ -68,21 +71,31 @@ func UpdateRateLimitXDSCacheForCustomPolicies(customRateLimitPolicies dpv1alpha1 } // DeleteAPILevelRateLimitPolicies delete the ratelimit xds cache -func DeleteAPILevelRateLimitPolicies(resolveRatelimit dpv1alpha1.ResolveRateLimitAPIPolicy) { - var org = resolveRatelimit.Organization - var environment = resolveRatelimit.Environment - var basePath = resolveRatelimit.BasePath - rlsPolicyCache.DeleteAPILevelRateLimitPolicies(org, environment, basePath) +func DeleteAPILevelRateLimitPolicies(resolveRatelimitPolicyList []dpv1alpha1.ResolveRateLimitAPIPolicy) { + + for _, resolveRatelimit := range resolveRatelimitPolicyList { + var org = resolveRatelimit.Organization + var environment = resolveRatelimit.Environment + var basePath = resolveRatelimit.BasePath + rlsPolicyCache.DeleteAPILevelRateLimitPolicies(org, environment, basePath) + } } // DeleteResourceLevelRateLimitPolicies delete the ratelimit xds cache -func DeleteResourceLevelRateLimitPolicies(resolveRatelimit dpv1alpha1.ResolveRateLimitAPIPolicy) { - var org = resolveRatelimit.Organization - var environment = resolveRatelimit.Environment - var basePath = resolveRatelimit.BasePath - var path = resolveRatelimit.Resources[0].Path - var method = resolveRatelimit.Resources[0].Method - rlsPolicyCache.DeleteResourceLevelRateLimitPolicies(org, environment, basePath, path, method) +func DeleteResourceLevelRateLimitPolicies(resolveRatelimitPolicyList []dpv1alpha1.ResolveRateLimitAPIPolicy) { + + for _, resolveRatelimit := range resolveRatelimitPolicyList { + + if resolveRatelimit.Resources == nil || len(resolveRatelimit.Resources) == 0 { + continue + } + var org = resolveRatelimit.Organization + var environment = resolveRatelimit.Environment + var basePath = resolveRatelimit.BasePath + var path = resolveRatelimit.Resources[0].Path + var method = resolveRatelimit.Resources[0].Method + rlsPolicyCache.DeleteResourceLevelRateLimitPolicies(org, environment, basePath, path, method) + } } // DeleteCustomRateLimitPolicies delete the ratelimit xds cache diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_conf.yaml b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_conf.yaml index 5d489245e3..afcde354c5 100644 --- a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_conf.yaml +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_conf.yaml @@ -8,6 +8,8 @@ defaultVersion: false endpointConfigurations: production: endpoint: "http://backend:80/anything" + sandbox: + endpoint: "http://backend:80/anything" operations: - target: "/employee" verb: "GET" diff --git a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_resource_conf.yaml b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_resource_conf.yaml index a5ca777455..33ec6a9517 100644 --- a/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_resource_conf.yaml +++ b/test/cucumber-tests/src/test/resources/artifacts/apk-confs/simple_rl_resource_conf.yaml @@ -8,6 +8,8 @@ defaultVersion: false endpointConfigurations: production: endpoint: "http://backend:80/anything" + sandbox: + endpoint: "http://backend:80/anything" operations: - target: "/employee" verb: "GET" diff --git a/test/cucumber-tests/src/test/resources/tests/api/SimpleRateLimit.feature b/test/cucumber-tests/src/test/resources/tests/api/SimpleRateLimit.feature index c1556eb130..7b88660c50 100644 --- a/test/cucumber-tests/src/test/resources/tests/api/SimpleRateLimit.feature +++ b/test/cucumber-tests/src/test/resources/tests/api/SimpleRateLimit.feature @@ -15,6 +15,8 @@ Feature: Test simple rate limit feature |401| And I send "GET" request to "https://default.gw.wso2.com:9095/simple-rl/3.14/employee/" with body "" Then the response status code should be 429 + And I send "GET" request to "https://default.sandbox.gw.wso2.com:9095/simple-rl/3.14/employee/" with body "" + Then the response status code should be 429 Scenario: Test simple rate limit api level for unsecured api Given The system is ready @@ -48,6 +50,12 @@ Feature: Test simple rate limit feature |401| And I send "POST" request to "https://default.gw.wso2.com:9095/simple-rl-r/3.14/employee/" with body "" Then the response status code should be 429 + And I send "POST" request to "https://default.sandbox.gw.wso2.com:9095/simple-rl-r/3.14/employee/" with body "" + And I eventually receive 200 response code, not accepting + |429| + |401| + And I send "POST" request to "https://default.sandbox.gw.wso2.com:9095/simple-rl-r/3.14/employee/" with body "" + Then the response status code should be 429 And I wait for next minute And I send "GET" request to "https://default.gw.wso2.com:9095/simple-rl-r/3.14/employee/" with body "" Then the response status code should be 200