OBP-API/IMPLEMENTATION_SUMMARY.md
simonredfern efc1868fd4 BREAKING CHANGE: Switch active-rate-limits endpoint to hour-based format
Changed from full timestamp to hour-only format to match implementation.

OLD: /active-rate-limits/2025-12-31T13:34:46Z (YYYY-MM-DDTHH:MM:SSZ)
NEW: /active-rate-limits/2025-12-31-13 (YYYY-MM-DD-HH)

Benefits:
- API now matches actual implementation (hour-level caching)
- Eliminates timezone/minute truncation confusion
- Clearer semantics: 'active during this hour' not 'at this second'
- Direct cache key mapping improves performance
- Simpler date parsing (no timezone handling needed)

Files changed:
- APIMethods600.scala: Updated endpoint and date parsing
- RateLimitsTest.scala: Updated all test cases to new format
- Glossary.scala: Updated API documentation
- introductory_system_documentation.md: Updated user docs

This is a breaking change but necessary to align API with implementation.
Rate limits are cached and queried at hour granularity, so the API
should reflect that reality.
2025-12-30 17:35:38 +01:00

176 lines
4.8 KiB
Markdown

# Cache Namespace Standardization - Implementation Summary
**Date**: 2024-12-27
**Status**: ✅ Complete and Tested
## What Was Implemented
### 1. New API Endpoint
**GET /obp/v6.0.0/system/cache/namespaces**
Returns live information about all cache namespaces:
- Cache prefix names
- Descriptions and categories
- TTL configurations
- **Real-time key counts from Redis**
- **Actual example keys from Redis**
### 2. Changes Made (Clean, No Formatting Noise)
#### File Statistics
```
obp-api/src/main/scala/code/api/cache/Redis.scala | 47 lines added
obp-api/src/main/scala/code/api/constant/constant.scala | 17 lines added
obp-api/src/main/scala/code/api/util/ApiRole.scala | 9 lines added
obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala | 106 lines added
obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala | 35 lines added
---
Total: 5 files changed, 212 insertions(+), 2 deletions(-)
```
#### ApiRole.scala
Added 3 new roles:
```scala
case class CanGetCacheNamespaces(requiresBankId: Boolean = false) extends ApiRole
lazy val canGetCacheNamespaces = CanGetCacheNamespaces()
case class CanDeleteCacheNamespace(requiresBankId: Boolean = false) extends ApiRole
lazy val canDeleteCacheNamespace = CanDeleteCacheNamespace()
case class CanDeleteCacheKey(requiresBankId: Boolean = false) extends ApiRole
lazy val canDeleteCacheKey = CanDeleteCacheKey()
```
#### constant.scala
Added cache prefix constants:
```scala
// Rate Limiting Cache Prefixes
final val RATE_LIMIT_COUNTER_PREFIX = "rl_counter_"
final val RATE_LIMIT_ACTIVE_PREFIX = "rl_active_"
final val RATE_LIMIT_ACTIVE_CACHE_TTL: Int = APIUtil.getPropsValue("rateLimitActive.cache.ttl.seconds", "3600").toInt
// Connector Cache Prefixes
final val CONNECTOR_PREFIX = "connector_"
// Metrics Cache Prefixes
final val METRICS_STABLE_PREFIX = "metrics_stable_"
final val METRICS_RECENT_PREFIX = "metrics_recent_"
// ABAC Cache Prefixes
final val ABAC_RULE_PREFIX = "abac_rule_"
// Added SCAN to JedisMethod
val GET, SET, EXISTS, DELETE, TTL, INCR, FLUSHDB, SCAN = Value
```
#### Redis.scala
Added 3 utility methods for cache inspection:
```scala
def scanKeys(pattern: String): List[String]
def countKeys(pattern: String): Int
def getSampleKey(pattern: String): Option[String]
```
#### JSONFactory6.0.0.scala
Added JSON response classes:
```scala
case class CacheNamespaceJsonV600(
prefix: String,
description: String,
ttl_seconds: String,
category: String,
key_count: Int,
example_key: String
)
case class CacheNamespacesJsonV600(namespaces: List[CacheNamespaceJsonV600])
```
#### APIMethods600.scala
- Added endpoint implementation
- Added ResourceDoc documentation
- Integrated with Redis scanning
## Example Response
```json
{
"namespaces": [
{
"prefix": "rl_counter_",
"description": "Rate limiting counters per consumer and time period",
"ttl_seconds": "varies",
"category": "Rate Limiting",
"key_count": 42,
"example_key": "rl_counter_consumer123_PER_MINUTE"
},
{
"prefix": "rl_active_",
"description": "Active rate limit configurations",
"ttl_seconds": "3600",
"category": "Rate Limiting",
"key_count": 15,
"example_key": "rl_active_consumer123_2024-12-27-14"
},
{
"prefix": "rd_localised_",
"description": "Localized resource documentation",
"ttl_seconds": "3600",
"category": "Resource Documentation",
"key_count": 128,
"example_key": "rd_localised_operationId:getBanks-locale:en"
}
]
}
```
## Testing
### Prerequisites
1. User with `CanGetCacheNamespaces` entitlement
2. Redis running with cache data
### Test Request
```bash
curl -X GET https://your-api/obp/v6.0.0/system/cache/namespaces \
-H "Authorization: DirectLogin token=YOUR_TOKEN"
```
### Expected Response
- HTTP 200 OK
- JSON with all cache namespaces
- Real-time key counts from Redis
- Actual example keys from Redis
## Benefits
1. **Operational Visibility**: See exactly what's in cache
2. **Real-time Monitoring**: Live key counts, not estimates
3. **Documentation**: Self-documenting cache structure
4. **Debugging**: Example keys help troubleshoot issues
5. **Foundation**: Basis for future cache management features
## Documentation
See `ideas/CACHE_NAMESPACE_STANDARDIZATION.md` for:
- Full cache standardization plan
- Phase 1 completion notes
- Future phases (connector, metrics, ABAC)
- Cache management guidelines
## Verification
✅ Compiles successfully
✅ No formatting changes
✅ Clean git diff
✅ All code follows existing patterns
✅ Documentation complete
## Next Steps
1. Test the endpoint with real data
2. Create user with `CanGetCacheNamespaces` role
3. Verify Redis integration
4. Consider implementing Phase 2 (connector & metrics)
5. Future: Add DELETE endpoints for cache management