Skip to content

Commit 16267d7

Browse files
committed
WS-2124: Update TTL for profile in the cache to match user token exp. date - COMPLETE
1 parent 3f12b39 commit 16267d7

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

src/lua/api-gateway/validation/oauth2/oauthTokenValidator.lua

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
-- 1. oauth_token_scope
1717
-- 2. oauth_token_client_id
1818
-- 3. oauth_token_user_id
19+
-- 4. oauth_token_expires_at
1920

2021
local BaseValidator = require "api-gateway.validation.validator"
2122
local cjson = require "cjson"
@@ -47,8 +48,8 @@ end
4748
-- @param json Token info object
4849
--
4950
function _M:isCachedTokenValid(json)
50-
local expires_in_ms = self:getExpiresIn(json.oauth_token_expires_at)
51-
return expires_in_ms
51+
local expires_in_s = self:getExpiresIn(json.oauth_token_expires_at)
52+
return expires_in_s
5253
end
5354

5455
-- returns the key that should be used when looking up in the cache --
@@ -61,23 +62,32 @@ function _M:getOauthTokenForCaching(token, oauth_host)
6162
end
6263
end
6364

64-
--- Converts the expire_at into expire_in
65-
-- @param expire_at UTC expiration time in ms
65+
--- Converts the expire_at into expire_in in seconds
66+
-- @param expire_at UTC expiration time in seconds
6667
--
6768
function _M:getExpiresIn(expire_at)
68-
local local_t = os.time() * 1000
69-
local expires_in_ms = expire_at - local_t
70-
return expires_in_ms
69+
if ( expire_at == nil ) then
70+
return LOCAL_CACHE_TTL
71+
end
72+
73+
local expire_at_s = expire_at
74+
if expire_at_s > 9999999999 then
75+
expire_at_s = expire_at / 1000
76+
end
77+
78+
local local_t = os.time()
79+
local expires_in_s = expire_at_s - local_t
80+
return expires_in_s
7181
end
7282

7383
function _M:storeTokenInCache(cacheLookupKey, cachingObj, expire_at_ms_utc)
74-
local expires_in_ms = self:getExpiresIn(expire_at_ms_utc)
75-
if ( expires_in_ms <= 0 ) then
84+
local expires_in_s = self:getExpiresIn(expire_at_ms_utc)
85+
if ( expires_in_s <= 0 ) then
7686
ngx.log(ngx.DEBUG, "OAuth Token was not persisted in the cache as it has expired at:" .. tostring(expire_at_ms_utc) .. ", while now is:" .. tostring(os.time() * 1000) .. " ms.")
7787
return nil
7888
end
79-
local local_expire_in = math.min( expires_in_ms / 1000, LOCAL_CACHE_TTL )
80-
ngx.log(ngx.DEBUG, "Storing a new token expiring in " .. tostring(local_expire_in) .. " s locally, out of a total validity of " .. tostring(expires_in_ms / 1000) .. " s.")
89+
local local_expire_in = math.min( expires_in_s, LOCAL_CACHE_TTL )
90+
ngx.log(ngx.DEBUG, "Storing a new token expiring in " .. tostring(local_expire_in) .. " s locally, out of a total validity of " .. tostring(expires_in_s) .. " s.")
8191
local cachingObjString = cjson.encode(cachingObj)
8292
self:setKeyInLocalCache(cacheLookupKey, cachingObjString, local_expire_in, "cachedOauthTokens")
8393
self:setKeyInRedis(cacheLookupKey, "token_json", expire_at_ms_utc, cachingObjString)
@@ -157,8 +167,8 @@ function _M:validate_ims_token()
157167
local obj = cjson.decode(cachedToken)
158168
local tokenValidity, error = self:isCachedTokenValid(obj)
159169
if tokenValidity > 0 then
160-
local local_expire_in = math.min( tokenValidity / 1000, LOCAL_CACHE_TTL )
161-
ngx.log(ngx.DEBUG, "Caching locally a new token for " .. tostring(local_expire_in) .. " s, out of a total validity of " .. tostring(tokenValidity / 1000) .. " s.")
170+
local local_expire_in = math.min( tokenValidity, LOCAL_CACHE_TTL )
171+
ngx.log(ngx.DEBUG, "Caching locally a new token for " .. tostring(local_expire_in) .. " s, out of a total validity of " .. tostring(tokenValidity ) .. " s.")
162172
self:setKeyInLocalCache(cacheLookupKey, cachedToken, local_expire_in , "cachedOauthTokens")
163173
self:setContextProperties(obj)
164174
return self:exitFn(ngx.HTTP_OK)

src/lua/api-gateway/validation/oauth2/userProfileValidator.lua

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
-- 2. ngx.var.authtoken - required to be set
88
-- 3. ngx.var.redis_backend - required
99
-- 4. lua_shared_dict cachedOauthTokens 50m; - required. The local shared dict to cache user profiles
10+
-- 5. ngx.ctx.oauth_token_expires_at - optional. This is usually set by the oauthTokenValidator
1011
--
1112
-- Properties that can be set by this validator:
1213
-- 1. user_email
@@ -44,6 +45,10 @@ local DEFAULT_COUNTRY_MAP = {
4445
AP = { "AU", "AF", "AQ", "BH", "BD", "BT", "BN", "MM", "KH", "CN", "CX", "CC", "CK", "TL", "FJ", "PF", "HK", "IN", "ID", "IQ", "IL", "JP", "JO", "KZ", "KI", "KR", "KW", "KG", "LA", "LB", "MO", "MY", "MV", "MH", "FM", "MN", "NR", "NP", "NC", "NZ", "NU", "NF", "OM", "PK", "PG", "PH", "PN", "QA", "RU", "WS", "SA", "SG", "SB", "LK", "TW", "TJ", "TH", "TK", "TO", "TR", "TM", "TV", "AE", "UZ", "VU", "VN", "WF", "YE" }
4546
}
4647

48+
---
49+
-- Maximum time in seconds specifying how long to cache a valid token in GW's memory
50+
local LOCAL_CACHE_TTL = 60
51+
4752
-- returns the key that should be used when looking up in the cache --
4853
function _M:getCacheToken(token)
4954
local t = token;
@@ -55,6 +60,24 @@ function _M:getCacheToken(token)
5560
end
5661
end
5762

63+
--- Converts the expire_at into expire_in in seconds
64+
-- @param expire_at UTC expiration time in seconds
65+
--
66+
function _M:getExpiresIn(expire_at)
67+
if ( expire_at == nil ) then
68+
return LOCAL_CACHE_TTL
69+
end
70+
71+
local expire_at_s = expire_at
72+
if expire_at_s > 9999999999 then
73+
expire_at_s = expire_at / 1000
74+
end
75+
76+
local local_t = os.time()
77+
local expires_in_s = expire_at_s - local_t
78+
return expires_in_s
79+
end
80+
5881
function _M:getProfileFromCache(cacheLookupKey)
5982
local localCacheValue = self:getKeyFromLocalCache(cacheLookupKey, "cachedUserProfiles")
6083
if ( localCacheValue ~= nil ) then
@@ -64,19 +87,28 @@ function _M:getProfileFromCache(cacheLookupKey)
6487

6588
local redisCacheValue = self:getKeyFromRedis(cacheLookupKey, "user_json")
6689
if ( redisCacheValue ~= nil ) then
67-
-- ngx.log(ngx.WARN, "Found profile in redis cache")
68-
self:setKeyInLocalCache(cacheLookupKey, redisCacheValue, 60, "cachedUserProfiles")
90+
ngx.log(ngx.DEBUG, "Found User Profile in Redis cache")
91+
local oauthTokenExpiration = ngx.ctx.oauth_token_expires_at
92+
local expiresIn = self:getExpiresIn(oauthTokenExpiration)
93+
local localExpiresIn = math.min( expiresIn, LOCAL_CACHE_TTL )
94+
ngx.log(ngx.DEBUG, "Storing cached User Profile in the local cache for " .. tostring(localExpiresIn) .. " s out of a total validity of " .. tostring(expiresIn) .. " s.")
95+
self:setKeyInLocalCache(cacheLookupKey, redisCacheValue, localExpiresIn, "cachedUserProfiles")
6996
return redisCacheValue
7097
end
7198
return nil;
7299
end
73100

74101
function _M:storeProfileInCache(cacheLookupKey, cachingObj)
75102
local cachingObjString = cjson.encode(cachingObj)
76-
-- TODO: find a better way to compute the expiry time
77-
self:setKeyInLocalCache(cacheLookupKey, cachingObjString, 60, "cachedUserProfiles")
103+
104+
local oauthTokenExpiration = ngx.ctx.oauth_token_expires_at
105+
local expiresIn = self:getExpiresIn(oauthTokenExpiration)
106+
local localExpiresIn = math.min( expiresIn, LOCAL_CACHE_TTL )
107+
ngx.log(ngx.DEBUG, "Storing new cached User Profile in the local cache for " .. tostring(localExpiresIn) .. " s out of a total validity of " .. tostring(expiresIn) .. " s.")
108+
109+
self:setKeyInLocalCache(cacheLookupKey, cachingObjString, localExpiresIn , "cachedUserProfiles")
78110
-- cache the use profile for 5 minutes
79-
self:setKeyInRedis(cacheLookupKey, "user_json", ((os.time() + 300) * 1000 ), cachingObjString)
111+
self:setKeyInRedis(cacheLookupKey, "user_json", oauthTokenExpiration or ((os.time() + LOCAL_CACHE_TTL) * 1000 ), cachingObjString)
80112
end
81113

82114
--- Returns true if the profile is valid for the request context
@@ -106,6 +138,8 @@ end
106138

107139
---
108140
-- Returns an object with a set of variables to be saved in the request's context and later in the request's vars
141+
-- IMPORTANT: This method is only called when fetching a new profile, otherwise the information from the cache
142+
-- is read and automatically added to the context based on the object returned by this method
109143
-- @param profile User Profile
110144
--
111145
function _M:extractContextVars(profile)

0 commit comments

Comments
 (0)