mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 11:06:49 +00:00
Added GET system cache config and GET system cache info
This commit is contained in:
parent
423a6000b0
commit
4a20168da7
@ -412,6 +412,12 @@ object ApiRole extends MdcLoggable{
|
||||
lazy val canGetMetricsAtOneBank = CanGetMetricsAtOneBank()
|
||||
|
||||
case class CanGetConfig(requiresBankId: Boolean = false) extends ApiRole
|
||||
case class CanGetCacheConfig(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canGetCacheConfig = CanGetCacheConfig()
|
||||
|
||||
case class CanGetCacheInfo(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canGetCacheInfo = CanGetCacheInfo()
|
||||
|
||||
|
||||
case class CanGetCacheNamespaces(requiresBankId: Boolean = false) extends ApiRole
|
||||
lazy val canGetCacheNamespaces = CanGetCacheNamespaces()
|
||||
|
||||
@ -27,7 +27,7 @@ import code.api.v5_0_0.{ViewJsonV500, ViewsJsonV500}
|
||||
import code.api.v5_1_0.{JSONFactory510, PostCustomerLegalNameJsonV510}
|
||||
import code.api.dynamic.entity.helper.{DynamicEntityHelper, DynamicEntityInfo}
|
||||
import code.api.v6_0_0.JSONFactory600.{AddUserToGroupResponseJsonV600, DynamicEntityDiagnosticsJsonV600, DynamicEntityIssueJsonV600, GroupEntitlementJsonV600, GroupEntitlementsJsonV600, GroupJsonV600, GroupsJsonV600, PostGroupJsonV600, PostGroupMembershipJsonV600, PostResetPasswordUrlJsonV600, PutGroupJsonV600, ReferenceTypeJsonV600, ReferenceTypesJsonV600, ResetPasswordUrlJsonV600, RoleWithEntitlementCountJsonV600, RolesWithEntitlementCountsJsonV600, ScannedApiVersionJsonV600, UpdateViewJsonV600, UserGroupMembershipJsonV600, UserGroupMembershipsJsonV600, ValidateUserEmailJsonV600, ValidateUserEmailResponseJsonV600, ViewJsonV600, ViewPermissionJsonV600, ViewPermissionsJsonV600, ViewsJsonV600, createAbacRuleJsonV600, createAbacRulesJsonV600, createActiveRateLimitsJsonV600, createCallLimitJsonV600, createRedisCallCountersJson}
|
||||
import code.api.v6_0_0.{AbacRuleJsonV600, AbacRuleResultJsonV600, AbacRulesJsonV600, CreateAbacRuleJsonV600, CurrentConsumerJsonV600, ExecuteAbacRuleJsonV600, UpdateAbacRuleJsonV600}
|
||||
import code.api.v6_0_0.{AbacRuleJsonV600, AbacRuleResultJsonV600, AbacRulesJsonV600, CacheConfigJsonV600, CacheInfoJsonV600, CacheNamespaceInfoJsonV600, CacheProviderConfigJsonV600, CreateAbacRuleJsonV600, CurrentConsumerJsonV600, ExecuteAbacRuleJsonV600, UpdateAbacRuleJsonV600}
|
||||
import code.api.v6_0_0.OBPAPI6_0_0
|
||||
import code.abacrule.{AbacRuleEngine, MappedAbacRuleProvider}
|
||||
import code.metrics.APIMetrics
|
||||
@ -658,6 +658,133 @@ trait APIMethods600 {
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
getCacheConfig,
|
||||
implementedInApiVersion,
|
||||
nameOf(getCacheConfig),
|
||||
"GET",
|
||||
"/system/cache/config",
|
||||
"Get Cache Configuration",
|
||||
"""Returns cache configuration information including:
|
||||
|
|
||||
|- Available cache providers (Redis, In-Memory)
|
||||
|- Redis connection details (URL, port, SSL)
|
||||
|- Instance ID and environment
|
||||
|- Global cache namespace prefix
|
||||
|
|
||||
|This helps understand what cache backend is being used and how it's configured.
|
||||
|
|
||||
|Authentication is Required
|
||||
|""",
|
||||
EmptyBody,
|
||||
CacheConfigJsonV600(
|
||||
providers = List(
|
||||
CacheProviderConfigJsonV600(
|
||||
provider = "redis",
|
||||
enabled = true,
|
||||
url = Some("127.0.0.1"),
|
||||
port = Some(6379),
|
||||
use_ssl = Some(false)
|
||||
),
|
||||
CacheProviderConfigJsonV600(
|
||||
provider = "in_memory",
|
||||
enabled = true,
|
||||
url = None,
|
||||
port = None,
|
||||
use_ssl = None
|
||||
)
|
||||
),
|
||||
instance_id = "obp",
|
||||
environment = "dev",
|
||||
global_prefix = "obp_dev_"
|
||||
),
|
||||
List(
|
||||
UserNotLoggedIn,
|
||||
UserHasMissingRoles,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagCache, apiTagSystem, apiTagApi),
|
||||
Some(List(canGetCacheConfig))
|
||||
)
|
||||
|
||||
lazy val getCacheConfig: OBPEndpoint = {
|
||||
case "system" :: "cache" :: "config" :: Nil JsonGet _ => {
|
||||
cc => implicit val ec = EndpointContext(Some(cc))
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
_ <- NewStyle.function.hasEntitlement("", u.userId, canGetCacheConfig, callContext)
|
||||
} yield {
|
||||
val result = JSONFactory600.createCacheConfigJsonV600()
|
||||
(result, HttpCode.`200`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
staticResourceDocs += ResourceDoc(
|
||||
getCacheInfo,
|
||||
implementedInApiVersion,
|
||||
nameOf(getCacheInfo),
|
||||
"GET",
|
||||
"/system/cache/info",
|
||||
"Get Cache Information",
|
||||
"""Returns detailed cache information for all namespaces:
|
||||
|
|
||||
|- Namespace ID and versioned prefix
|
||||
|- Current version counter
|
||||
|- Number of keys in each namespace
|
||||
|- Description and category
|
||||
|- Total key count across all namespaces
|
||||
|- Redis availability status
|
||||
|
|
||||
|This endpoint helps monitor cache usage and identify which namespaces contain the most data.
|
||||
|
|
||||
|Authentication is Required
|
||||
|""",
|
||||
EmptyBody,
|
||||
CacheInfoJsonV600(
|
||||
namespaces = List(
|
||||
CacheNamespaceInfoJsonV600(
|
||||
namespace_id = "call_counter",
|
||||
prefix = "obp_dev_call_counter_1_",
|
||||
current_version = 1,
|
||||
key_count = 42,
|
||||
description = "Rate limit call counters",
|
||||
category = "Rate Limiting"
|
||||
),
|
||||
CacheNamespaceInfoJsonV600(
|
||||
namespace_id = "rd_localised",
|
||||
prefix = "obp_dev_rd_localised_1_",
|
||||
current_version = 1,
|
||||
key_count = 128,
|
||||
description = "Localized resource docs",
|
||||
category = "API Documentation"
|
||||
)
|
||||
),
|
||||
total_keys = 170,
|
||||
redis_available = true
|
||||
),
|
||||
List(
|
||||
UserNotLoggedIn,
|
||||
UserHasMissingRoles,
|
||||
UnknownError
|
||||
),
|
||||
List(apiTagCache, apiTagSystem, apiTagApi),
|
||||
Some(List(canGetCacheInfo))
|
||||
)
|
||||
|
||||
lazy val getCacheInfo: OBPEndpoint = {
|
||||
case "system" :: "cache" :: "info" :: Nil JsonGet _ => {
|
||||
cc => implicit val ec = EndpointContext(Some(cc))
|
||||
for {
|
||||
(Full(u), callContext) <- authenticatedAccess(cc)
|
||||
_ <- NewStyle.function.hasEntitlement("", u.userId, canGetCacheInfo, callContext)
|
||||
} yield {
|
||||
val result = JSONFactory600.createCacheInfoJsonV600()
|
||||
(result, HttpCode.`200`(callContext))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy val getCurrentConsumer: OBPEndpoint = {
|
||||
case "consumers" :: "current" :: Nil JsonGet _ => {
|
||||
cc => {
|
||||
|
||||
@ -268,6 +268,36 @@ case class InvalidatedCacheNamespaceJsonV600(
|
||||
status: String
|
||||
)
|
||||
|
||||
case class CacheProviderConfigJsonV600(
|
||||
provider: String,
|
||||
enabled: Boolean,
|
||||
url: Option[String],
|
||||
port: Option[Int],
|
||||
use_ssl: Option[Boolean]
|
||||
)
|
||||
|
||||
case class CacheConfigJsonV600(
|
||||
providers: List[CacheProviderConfigJsonV600],
|
||||
instance_id: String,
|
||||
environment: String,
|
||||
global_prefix: String
|
||||
)
|
||||
|
||||
case class CacheNamespaceInfoJsonV600(
|
||||
namespace_id: String,
|
||||
prefix: String,
|
||||
current_version: Long,
|
||||
key_count: Int,
|
||||
description: String,
|
||||
category: String
|
||||
)
|
||||
|
||||
case class CacheInfoJsonV600(
|
||||
namespaces: List[CacheNamespaceInfoJsonV600],
|
||||
total_keys: Int,
|
||||
redis_available: Boolean
|
||||
)
|
||||
|
||||
case class PostCustomerJsonV600(
|
||||
legal_name: String,
|
||||
customer_number: Option[String] = None,
|
||||
@ -1083,4 +1113,97 @@ object JSONFactory600 extends CustomJsonFormats with MdcLoggable {
|
||||
): CacheNamespacesJsonV600 = {
|
||||
CacheNamespacesJsonV600(namespaces)
|
||||
}
|
||||
|
||||
def createCacheConfigJsonV600(): CacheConfigJsonV600 = {
|
||||
import code.api.cache.{Redis, InMemory}
|
||||
import code.api.Constant
|
||||
import net.liftweb.util.Props
|
||||
|
||||
val redisProvider = CacheProviderConfigJsonV600(
|
||||
provider = "redis",
|
||||
enabled = true,
|
||||
url = Some(Redis.url),
|
||||
port = Some(Redis.port),
|
||||
use_ssl = Some(Redis.useSsl)
|
||||
)
|
||||
|
||||
val inMemoryProvider = CacheProviderConfigJsonV600(
|
||||
provider = "in_memory",
|
||||
enabled = true,
|
||||
url = None,
|
||||
port = None,
|
||||
use_ssl = None
|
||||
)
|
||||
|
||||
val instanceId = code.api.util.APIUtil.getPropsValue("api_instance_id").getOrElse("obp")
|
||||
val environment = Props.mode match {
|
||||
case Props.RunModes.Production => "prod"
|
||||
case Props.RunModes.Staging => "staging"
|
||||
case Props.RunModes.Development => "dev"
|
||||
case Props.RunModes.Test => "test"
|
||||
case _ => "unknown"
|
||||
}
|
||||
|
||||
CacheConfigJsonV600(
|
||||
providers = List(redisProvider, inMemoryProvider),
|
||||
instance_id = instanceId,
|
||||
environment = environment,
|
||||
global_prefix = Constant.getGlobalCacheNamespacePrefix
|
||||
)
|
||||
}
|
||||
|
||||
def createCacheInfoJsonV600(): CacheInfoJsonV600 = {
|
||||
import code.api.cache.Redis
|
||||
import code.api.Constant
|
||||
|
||||
val namespaceDescriptions = Map(
|
||||
Constant.CALL_COUNTER_NAMESPACE -> ("Rate limit call counters", "Rate Limiting"),
|
||||
Constant.RL_ACTIVE_NAMESPACE -> ("Active rate limit states", "Rate Limiting"),
|
||||
Constant.RD_LOCALISED_NAMESPACE -> ("Localized resource docs", "API Documentation"),
|
||||
Constant.RD_DYNAMIC_NAMESPACE -> ("Dynamic resource docs", "API Documentation"),
|
||||
Constant.RD_STATIC_NAMESPACE -> ("Static resource docs", "API Documentation"),
|
||||
Constant.RD_ALL_NAMESPACE -> ("All resource docs", "API Documentation"),
|
||||
Constant.SWAGGER_STATIC_NAMESPACE -> ("Static Swagger docs", "API Documentation"),
|
||||
Constant.CONNECTOR_NAMESPACE -> ("Connector cache", "Connector"),
|
||||
Constant.METRICS_STABLE_NAMESPACE -> ("Stable metrics data", "Metrics"),
|
||||
Constant.METRICS_RECENT_NAMESPACE -> ("Recent metrics data", "Metrics"),
|
||||
Constant.ABAC_RULE_NAMESPACE -> ("ABAC rule cache", "Authorization")
|
||||
)
|
||||
|
||||
var redisAvailable = true
|
||||
var totalKeys = 0
|
||||
|
||||
val namespaces = Constant.ALL_CACHE_NAMESPACES.map { namespaceId =>
|
||||
val version = Constant.getCacheNamespaceVersion(namespaceId)
|
||||
val prefix = Constant.getVersionedCachePrefix(namespaceId)
|
||||
val pattern = s"${prefix}*"
|
||||
|
||||
val keyCount = try {
|
||||
val count = Redis.countKeys(pattern)
|
||||
totalKeys += count
|
||||
count
|
||||
} catch {
|
||||
case _: Throwable =>
|
||||
redisAvailable = false
|
||||
0
|
||||
}
|
||||
|
||||
val (description, category) = namespaceDescriptions.getOrElse(namespaceId, ("Unknown namespace", "Other"))
|
||||
|
||||
CacheNamespaceInfoJsonV600(
|
||||
namespace_id = namespaceId,
|
||||
prefix = prefix,
|
||||
current_version = version,
|
||||
key_count = keyCount,
|
||||
description = description,
|
||||
category = category
|
||||
)
|
||||
}
|
||||
|
||||
CacheInfoJsonV600(
|
||||
namespaces = namespaces,
|
||||
total_keys = totalKeys,
|
||||
redis_available = redisAvailable
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user