diff --git a/obp-api/src/main/resources/props/sample.props.template b/obp-api/src/main/resources/props/sample.props.template index f9416680e..29e80e27b 100644 --- a/obp-api/src/main/resources/props/sample.props.template +++ b/obp-api/src/main/resources/props/sample.props.template @@ -970,9 +970,10 @@ featured_apis=elasticSearchWarehouseV300 # ---------------------------------------------- # -- Rate Limiting ----------------------------------- -# Define how many calls per hour a consumer can make -# In case isn't defined default value is "false" -# use_consumer_limits=false +# Enable consumer-specific rate limiting (queries RateLimiting table) +# Default is now true. This property may be removed in a future version. +# Set to false to use only system-wide defaults (not recommended) +# use_consumer_limits=true # In case isn't defined default value is 60 # user_consumer_limit_anonymous_access=100 # For the Rate Limiting feature we use Redis cache instance diff --git a/obp-api/src/main/scala/code/api/cache/Caching.scala b/obp-api/src/main/scala/code/api/cache/Caching.scala index 3b46ff5f2..413d1e700 100644 --- a/obp-api/src/main/scala/code/api/cache/Caching.scala +++ b/obp-api/src/main/scala/code/api/cache/Caching.scala @@ -100,5 +100,16 @@ object Caching extends MdcLoggable { Redis.deleteKeysByPattern(pattern) } + /** + * Invalidate ALL rate limit cache entries for ALL consumers. + * Use with caution - this clears the entire rate limiting cache namespace. + * + * @return Number of cache keys deleted + */ + def invalidateAllRateLimitCache(): Int = { + val pattern = s"${RATE_LIMIT_ACTIVE_PREFIX}*" + Redis.deleteKeysByPattern(pattern) + } + } diff --git a/obp-api/src/main/scala/code/api/util/RateLimitingUtil.scala b/obp-api/src/main/scala/code/api/util/RateLimitingUtil.scala index 97b501769..2564270ca 100644 --- a/obp-api/src/main/scala/code/api/util/RateLimitingUtil.scala +++ b/obp-api/src/main/scala/code/api/util/RateLimitingUtil.scala @@ -84,7 +84,7 @@ object RateLimitingUtil extends MdcLoggable { status: String // ACTIVE, NO_COUNTER, EXPIRED, REDIS_UNAVAILABLE ) - def useConsumerLimits = APIUtil.getPropsAsBoolValue("use_consumer_limits", false) + def useConsumerLimits = APIUtil.getPropsAsBoolValue("use_consumer_limits", true) /** Get system default rate limits from properties. Used when no RateLimiting records exist for a consumer. * @param consumerId The consumer ID diff --git a/obp-api/src/test/scala/code/api/v6_0_0/RateLimitsTest.scala b/obp-api/src/test/scala/code/api/v6_0_0/RateLimitsTest.scala index 7f1679fce..c33793f0d 100644 --- a/obp-api/src/test/scala/code/api/v6_0_0/RateLimitsTest.scala +++ b/obp-api/src/test/scala/code/api/v6_0_0/RateLimitsTest.scala @@ -198,8 +198,8 @@ class RateLimitsTest extends V600ServerSetup { getResponse.body.extract[ErrorMessage].message should equal(UserHasMissingRoles + CanGetRateLimits) } - // TODO: Implement cache invalidation before enabling this test - ignore("We will get aggregated call limits for two overlapping rate limit records", ApiEndpoint3, VersionOfApi) { + scenario("We will get aggregated call limits for two overlapping rate limit records", ApiEndpoint3, VersionOfApi) { + // NOTE: This test requires use_consumer_limits=true in props file Given("We create two call limit records with overlapping date ranges") val Some((c, _)) = user1 val consumerId = Consumers.consumers.vend.getConsumerByConsumerKey(c.key).map(_.consumerId.get).getOrElse("")