diff --git a/obp-api/src/main/resources/docs/introductory_system_documentation.md b/obp-api/src/main/resources/docs/introductory_system_documentation.md index b2b2b96e9..8ff3cff52 100644 --- a/obp-api/src/main/resources/docs/introductory_system_documentation.md +++ b/obp-api/src/main/resources/docs/introductory_system_documentation.md @@ -2834,9 +2834,14 @@ PUT /obp/v6.0.0/management/consumers/CONSUMER_ID/consumer/rate-limits/RATE_LIMIT } ``` +Query active rate limits (current date/time): +```bash +GET /obp/v6.0.0/management/consumers/CONSUMER_ID/active-rate-limits +``` + Query active rate limits at a specific date: ```bash -GET /obp/v6.0.0/management/consumers/CONSUMER_ID/consumer/active-rate-limits/DATE +GET /obp/v6.0.0/management/consumers/CONSUMER_ID/active-rate-limits/DATE ``` **Rate Limit Headers:** @@ -2858,6 +2863,11 @@ X-Rate-Limit-Reset: 45 - **Aggregation**: Active limits are summed together (positive values only) - **Single Source of Truth**: `RateLimitingUtil.getActiveRateLimitsWithIds()` calculates all active limits consistently - **Unlimited**: A value of `-1` means unlimited for that time period +X-Rate-Limit-Remaining: 0 +X-Rate-Limit-Reset: 45 + +{ +- **Unlimited**: A value of `-1` means unlimited for that time period ### 8.5 Security Best Practices diff --git a/obp-api/src/main/scala/code/api/util/Glossary.scala b/obp-api/src/main/scala/code/api/util/Glossary.scala index 6eaf4216d..be80b0749 100644 --- a/obp-api/src/main/scala/code/api/util/Glossary.scala +++ b/obp-api/src/main/scala/code/api/util/Glossary.scala @@ -300,7 +300,7 @@ object Glossary extends MdcLoggable { | |Use the endpoint: |``` - |GET /obp/v6.0.0/management/consumers/{CONSUMER_ID}/consumer/active-rate-limits/{DATE} + |GET /obp/v6.0.0/management/consumers/{CONSUMER_ID}/active-rate-limits/{DATE} |``` | |Returns the aggregated active rate limits at a specific date, including which rate limit records contributed to the totals. diff --git a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala index 2d1e80663..8bb5e7c59 100644 --- a/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala +++ b/obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala @@ -457,7 +457,7 @@ trait APIMethods600 { implementedInApiVersion, nameOf(getActiveRateLimitsAtDate), "GET", - "/management/consumers/CONSUMER_ID/consumer/active-rate-limits/DATE", + "/management/consumers/CONSUMER_ID/active-rate-limits/DATE", "Get Active Rate Limits at Date", s""" |Get the active rate limits for a consumer at a specific date. Returns the aggregated rate limits from all active records at that time. @@ -484,7 +484,7 @@ trait APIMethods600 { lazy val getActiveRateLimitsAtDate: OBPEndpoint = { - case "management" :: "consumers" :: consumerId :: "consumer" :: "active-rate-limits" :: dateString :: Nil JsonGet _ => + case "management" :: "consumers" :: consumerId :: "active-rate-limits" :: dateString :: Nil JsonGet _ => cc => implicit val ec = EndpointContext(Some(cc)) for { @@ -501,6 +501,52 @@ trait APIMethods600 { } } + + staticResourceDocs += ResourceDoc( + getActiveRateLimitsNow, + implementedInApiVersion, + nameOf(getActiveRateLimitsNow), + "GET", + "/management/consumers/CONSUMER_ID/active-rate-limits", + "Get Active Rate Limits (Current)", + s""" + |Get the active rate limits for a consumer at the current date/time. Returns the aggregated rate limits from all active records at this moment. + | + |This is a convenience endpoint that uses the current date/time automatically. + | + |See ${Glossary.getGlossaryItemLink("Rate Limiting")} for more details on how rate limiting works. + | + |${userAuthenticationMessage(true)} + | + |""".stripMargin, + EmptyBody, + activeCallLimitsJsonV600, + List( + $UserNotLoggedIn, + InvalidConsumerId, + ConsumerNotFoundByConsumerId, + UserHasMissingRoles, + UnknownError + ), + List(apiTagConsumer), + Some(List(canGetRateLimits))) + + + lazy val getActiveRateLimitsNow: OBPEndpoint = { + case "management" :: "consumers" :: consumerId :: "active-rate-limits" :: Nil JsonGet _ => + cc => + implicit val ec = EndpointContext(Some(cc)) + for { + (Full(u), callContext) <- authenticatedAccess(cc) + _ <- NewStyle.function.hasEntitlement("", u.userId, canGetRateLimits, callContext) + _ <- NewStyle.function.getConsumerByConsumerId(consumerId, callContext) + date = new java.util.Date() // Use current date/time + (rateLimit, rateLimitIds) <- RateLimitingUtil.getActiveRateLimitsWithIds(consumerId, date) + } yield { + (JSONFactory600.createActiveCallLimitsJsonV600FromCallLimit(rateLimit, rateLimitIds, date), HttpCode.`200`(callContext)) + } + } + staticResourceDocs += ResourceDoc( getDynamicEntityDiagnostics, implementedInApiVersion, 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 48e36d719..6797e33a9 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 @@ -171,7 +171,7 @@ class RateLimitsTest extends V600ServerSetup { val currentDateString = ZonedDateTime .now(ZoneOffset.UTC) .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")) - val getRequest = (v6_0_0_Request / "management" / "consumers" / consumerId / "consumer" / "active-rate-limits" / currentDateString).GET <@ (user1) + val getRequest = (v6_0_0_Request / "management" / "consumers" / consumerId / "active-rate-limits" / currentDateString).GET <@ (user1) val getResponse = makeGetRequest(getRequest) Then("We should get a 200") @@ -189,7 +189,7 @@ class RateLimitsTest extends V600ServerSetup { val currentDateString = ZonedDateTime .now(ZoneOffset.UTC) .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")) - val getRequest = (v6_0_0_Request / "management" / "consumers" / consumerId / "consumer" / "active-rate-limits" / currentDateString).GET <@ (user1) + val getRequest = (v6_0_0_Request / "management" / "consumers" / consumerId / "active-rate-limits" / currentDateString).GET <@ (user1) val getResponse = makeGetRequest(getRequest) Then("We should get a 403") @@ -248,7 +248,7 @@ class RateLimitsTest extends V600ServerSetup { .now(ZoneOffset.UTC) .plusDays(1) // Check 1 day from now (within the range) .format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")) - val getRequest = (v6_0_0_Request / "management" / "consumers" / consumerId / "consumer" / "active-rate-limits" / targetDate).GET <@ (user1) + val getRequest = (v6_0_0_Request / "management" / "consumers" / consumerId / "active-rate-limits" / targetDate).GET <@ (user1) val getResponse = makeGetRequest(getRequest) Then("We should get a 200")