mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 13:07:02 +00:00
RateLimitingUtil adding status to interpret redis key result
This commit is contained in:
parent
1fc0ab720c
commit
cd52665f35
@ -228,7 +228,7 @@ object RateLimitingUtil extends MdcLoggable {
|
||||
|
||||
def consumerRateLimitState(consumerKey: String): immutable.Seq[((Option[Long], Option[Long], String), LimitCallPeriod)] = {
|
||||
|
||||
def getCallCounterForPeriod(consumerKey: String, period: LimitCallPeriod): ((Option[Long], Option[Long]), LimitCallPeriod) = {
|
||||
def getCallCounterForPeriod(consumerKey: String, period: LimitCallPeriod): ((Option[Long], Option[Long], String), LimitCallPeriod) = {
|
||||
val key = createUniqueKey(consumerKey, period)
|
||||
|
||||
// get TTL
|
||||
@ -256,7 +256,16 @@ object RateLimitingUtil extends MdcLoggable {
|
||||
case None => Some(0L) // Redis unavailable -> 0 TTL
|
||||
}
|
||||
|
||||
((calls, normalizedTtl), period)
|
||||
|
||||
// Calculate status based on Redis TTL response
|
||||
val status = ttlOpt match {
|
||||
case Some(ttl) if ttl > 0 => "ACTIVE" // Counter running with time remaining
|
||||
case Some(-2) => "NO_COUNTER" // Key does not exist, never been set
|
||||
case Some(ttl) if ttl <= 0 => "EXPIRED" // Key expired (TTL=0) or no expiry (TTL=-1)
|
||||
case None => "REDIS_UNAVAILABLE" // Redis connection failed
|
||||
}
|
||||
|
||||
((calls, normalizedTtl, status), period)
|
||||
}
|
||||
|
||||
getCallCounterForPeriod(consumerKey, RateLimitingPeriod.PER_SECOND) ::
|
||||
|
||||
@ -809,7 +809,7 @@ object JSONFactory310{
|
||||
def createBadLoginStatusJson(badLoginStatus: BadLoginAttempt) : BadLoginStatusJson = {
|
||||
BadLoginStatusJson(badLoginStatus.username,badLoginStatus.badAttemptsSinceLastSuccessOrReset, badLoginStatus.lastFailureDate)
|
||||
}
|
||||
def createCallLimitJson(consumer: Consumer, rateLimits: List[((Option[Long], Option[Long]), LimitCallPeriod)]) : CallLimitJson = {
|
||||
def createCallLimitJson(consumer: Consumer, rateLimits: List[((Option[Long], Option[Long], String), LimitCallPeriod)]) : CallLimitJson = {
|
||||
val redisRateLimit = rateLimits match {
|
||||
case Nil => None
|
||||
case _ =>
|
||||
@ -817,7 +817,8 @@ object JSONFactory310{
|
||||
rateLimits.filter(_._2 == period) match {
|
||||
case x :: Nil =>
|
||||
x._1 match {
|
||||
case (Some(x), Some(y)) => Some(RateLimit(Some(x), Some(y)))
|
||||
case (Some(x), Some(y), _) => Some(RateLimit(Some(x), Some(y)))
|
||||
// Ignore status field for v3.1.0 API (backward compatibility)
|
||||
case _ => None
|
||||
|
||||
}
|
||||
|
||||
@ -236,7 +236,10 @@ trait APIMethods600 {
|
||||
|
|
||||
|**Status Values:**
|
||||
|- `ACTIVE`: Rate limit counter is active and tracking calls. Both `calls_made` and `reset_in_seconds` will have numeric values.
|
||||
|- `UNKNOWN`: Data is not available. This could mean the rate limit period has expired, no rate limit is configured, or the data cannot be retrieved. Both `calls_made` and `reset_in_seconds` will be null.
|
||||
|- `NO_COUNTER`: Key does not exist - the consumer has not made any API calls in this time period yet.
|
||||
|- `EXPIRED`: The rate limit counter has expired (TTL reached 0). The counter will be recreated on the next API call.
|
||||
|- `REDIS_UNAVAILABLE`: Cannot retrieve data from Redis. This indicates a system connectivity issue.
|
||||
|- `DATA_MISSING`: Unexpected error - period data is missing from the response. This should not occur under normal circumstances.
|
||||
|
|
||||
|${userAuthenticationMessage(true)}
|
||||
|
|
||||
|
||||
@ -402,19 +402,18 @@ object JSONFactory600 extends CustomJsonFormats with MdcLoggable {
|
||||
|
||||
def createRedisCallCountersJson(
|
||||
// Convert list to map for easy lookup by period
|
||||
rateLimits: List[((Option[Long], Option[Long]), LimitCallPeriod)]
|
||||
rateLimits: List[((Option[Long], Option[Long], String), LimitCallPeriod)]
|
||||
): RedisCallCountersJsonV600 = {
|
||||
val grouped: Map[LimitCallPeriod, (Option[Long], Option[Long])] =
|
||||
val grouped: Map[LimitCallPeriod, (Option[Long], Option[Long], String)] =
|
||||
rateLimits.map { case (limits, period) => period -> limits }.toMap
|
||||
|
||||
def getCallCounterForPeriod(period: RateLimitingPeriod.Value): RateLimitV600 =
|
||||
grouped.get(period) match {
|
||||
// ACTIVE: Both calls and TTL exist, and TTL > 0 (key has time remaining)
|
||||
// UNKNOWN: Missing data, TTL <= 0 (expired), or Redis unavailable
|
||||
case Some((Some(calls), Some(ttl))) if ttl > 0 =>
|
||||
RateLimitV600(Some(calls), Some(ttl), "ACTIVE")
|
||||
// Use status calculated by RateLimitingUtil (ACTIVE, NO_COUNTER, EXPIRED, REDIS_UNAVAILABLE)
|
||||
case Some((calls, ttl, status)) =>
|
||||
RateLimitV600(calls, ttl, status)
|
||||
case _ =>
|
||||
RateLimitV600(None, None, "UNKNOWN")
|
||||
RateLimitV600(None, None, "DATA_MISSING")
|
||||
}
|
||||
|
||||
RedisCallCountersJsonV600(
|
||||
@ -591,7 +590,7 @@ object JSONFactory600 extends CustomJsonFormats with MdcLoggable {
|
||||
}
|
||||
|
||||
def createActiveCallLimitsJsonV600FromCallLimit(
|
||||
|
||||
|
||||
rateLimit: code.api.util.RateLimitingJson.CallLimit,
|
||||
rateLimitIds: List[String],
|
||||
activeDate: java.util.Date
|
||||
|
||||
Loading…
Reference in New Issue
Block a user