rate-limits active Now

This commit is contained in:
simonredfern 2025-12-24 00:19:51 +01:00
parent a8cfac14cf
commit 0d4a3186e2
4 changed files with 63 additions and 7 deletions

View File

@ -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

View File

@ -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.

View File

@ -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,

View File

@ -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")