Commit aba81a58 authored by Renato Figueiro Maia's avatar Renato Figueiro Maia

[OPENBUS-1535] Refatorar os Serviços Básicos.

[OPENBUS-1538] Implementar a nova proposta do SDK OpenBus em Lua
- Correção da política de remoção das entradas de caches usado no acesso ao barramento que estava LAST INCLUDED ao invés de LEAST RECENTLY USED.


git-svn-id: https://subversion.tecgraf.puc-rio.br/engdist/openbus/sdk/lua/branches/openbus_v2_proto@128135 ae0415b3-e90b-0410-900d-d0be9363c56b
parent 17aeec72
......@@ -26,6 +26,7 @@ local table = require "loop.table"
local copy = table.copy
local memoize = table.memoize
local LRUCache = require "loop.collection.LRUCache"
local Wrapper = require "loop.object.Wrapper"
local Mutex = require "cothread.Mutex"
......@@ -35,8 +36,6 @@ local sysex = giop.SystemExceptionIDs
local log = require "openbus.util.logger"
local msg = require "openbus.util.messages"
local cache = require "openbus.util.cache"
local LRU = cache.LRU
local oo = require "openbus.util.oo"
local class = oo.class
......@@ -69,18 +68,7 @@ local function getEntryFromCache(self, loginId)
local validity = self.validity
local timeupdated = self.timeupdated
-- use information in the cache to validate the login
local entry = self.cache[loginId]
if entry.id == nil then
local ok, info, encodedkey = pcall(logins.getLoginInfo, logins, loginId)
if ok then
entry.entity = info.entity
entry.encodedkey = encodedkey
entry.pubkey = assert(decodepubkey(encodedkey))
elseif info._repid ~= logintypes.InvalidLogins then
error(info)
end
entry.id = loginId
end
local entry = self.logininfo:get(loginId)
local time2live = validity[entry.index]
if time2live == 0 then
log:LOGIN_CACHE(msg.InvalidLoginInValidityCache:tag{
......@@ -131,20 +119,32 @@ local function newLoginRegistryWrapper(logins)
validity = validity,
timeupdated = -inf,
mutex = Mutex(),
cache = LRU(function(loginId, replacedId, entry)
local index
if entry == nil then
index = #ids+1
entry = { index = index }
else
index = entry.index
entry.id = nil
entry.entity = nil
end
ids[index] = loginId
validity[index] = nil
return entry
end),
logininfo = LRUCache{
retrieve = function(loginId, replacedId, entry)
local index
if entry == nil then
index = #ids+1
entry = { index = index }
else
index = entry.index
entry.id = nil
entry.entity = nil
entry.pubkey = nil
end
local ok, info, enckey = pcall(logins.getLoginInfo, logins, loginId)
if ok then
entry.entity = info.entity
entry.encodedkey = enckey
entry.pubkey = assert(decodepubkey(enckey))
elseif info._repid ~= logintypes.InvalidLogins then
error(info)
end
entry.id = loginId
ids[index] = loginId
validity[index] = nil
return entry
end,
},
getLoginEntry = getLoginEntry,
getLoginInfo = getLoginInfo,
}
......
......@@ -25,6 +25,7 @@ local gettime = socket.gettime
local table = require "loop.table"
local clear = table.clear
local copy = table.copy
local memoize = table.memoize
local oil = require "oil"
local neworb = oil.init
......@@ -38,11 +39,11 @@ local sha256 = hash.sha256
local pubkey = require "lce.pubkey"
local newkey = pubkey.create
local LRUCache = require "loop.collection.LRUCache"
local log = require "openbus.util.logger"
local oo = require "openbus.util.oo"
local class = oo.class
local cache = require "openbus.util.cache"
local LRU = cache.LRU
local tickets = require "openbus.util.tickets"
local msg = require "openbus.core.messages"
......@@ -74,14 +75,6 @@ local WeakKeys = {__mode = "k"}
local CallChain = class()
function CallChain:__init()
self.joined = LRU(function(login) return false end)
end
local function calculateHash(secret, ticket, request)
return sha256(encode(
"<c2c0I4c0", -- '<' flag to set to little endian
......@@ -116,13 +109,7 @@ local function marshalCredential(self, request, credential, chain, remoteid)
legacy = false -- do not send legacy credential (OpenBus 1.5)
if remoteid ~= self.busid then
if chain == nil then chain = self.emptyChain end
local cache = chain.joined
local joined = cache[remoteid]
if not joined then
joined = self:joinedChainFor(remoteid, chain)
cache[remoteid] = joined
end
chain = joined
chain = self.signedChainOf[chain]:get(remoteid)
end
end
credential.chain = chain or NullChain
......@@ -185,7 +172,7 @@ local function unmarshalCredential(self, contexts)
login = loginId,
ticket = nil,
hash = nil,
}, CallChain{
}, {
encoded = nil,
signature = nil,
target = nil,
......@@ -265,18 +252,27 @@ function Interceptor:__init()
end
function Interceptor:resetCaches()
self.emptyChain = CallChain{ callers = {} }
self.callerChainOf = setmetatable({}, WeakKeys)
self.joinedChainOf = setmetatable({}, WeakKeys)
self.profile2login = LRU(function() return false end)
self.outgoingCredentials = LRU(function() return false end)
self.incomingCredentials = LRU(function(id)
return {
id = id,
secret = newSecret(),
tickets = tickets(),
self.emptyChain = { callers = {} }
self.callerChainOf = setmetatable({}, WeakKeys) -- [thread] = callerChain
self.joinedChainOf = setmetatable({}, WeakKeys) -- [thread] = joinedChain
self.signedChainOf = memoize(function(chain) -- [chain] = SignedChainCache
return LRUCache{
retrieve = function(remoteid)
return self:joinedChainFor(remoteid, chain)
end,
}
end)
end, "k")
self.profile2login = LRUCache()
self.outgoingSessions = LRUCache()
self.incomingSessions = LRUCache{
retrieve = function(id)
return {
id = id,
secret = newSecret(),
tickets = tickets(),
}
end,
}
end
function Interceptor:validateCredential(credential, request, remotekey)
......@@ -286,8 +282,7 @@ function Interceptor:validateCredential(credential, request, remotekey)
return true
end
-- get current credential session
local incoming = self.incomingCredentials
local session = rawget(incoming, credential.session)
local session = self.incomingSessions:rawget(credential.session)
if session ~= nil then
local ticket = credential.ticket
-- validate credential with current secret
......@@ -297,7 +292,7 @@ function Interceptor:validateCredential(credential, request, remotekey)
end
end
-- create a new session for the invalid credential
return false, incoming[#incoming+1]
return false
end
function Interceptor:validateChain(chain, caller)
......@@ -349,9 +344,9 @@ function Interceptor:sendrequest(request)
if login ~= nil then
-- check whether there is an active credential session for this IOR profile
local sessionid, ticket, hash
local remoteid = self.profile2login[request.profile_data]
local remoteid = self.profile2login:get(request.profile_data)
if remoteid then
local session = self.outgoingCredentials[remoteid]
local session = self.outgoingSessions:get(remoteid)
sessionid = session.id
ticket = session.ticket+1
session.ticket = ticket
......@@ -395,20 +390,15 @@ function Interceptor:receivereply(request)
-- got invalid credential exception
local reset = unmarshalReset(self, request)
if reset ~= nil then
-- get previous credential session information, if any
local profile = request.profile_data
local profile2login = self.profile2login
local previousid = profile2login[profile]
-- initialize session and set credential session information
local remoteid = reset.login
profile2login[profile] = remoteid
-- initialize session
local session = {
self.profile2login:put(request.profile_data, remoteid)
self.outgoingSessions:put(remoteid, {
id = reset.session,
secret = reset.secret,
remoteid = remoteid,
ticket = -1,
}
self.outgoingCredentials[remoteid] = session
})
log:access(msg.CredentialSessionReset:tag{
login = remoteid,
operation = request.operation_name,
......@@ -428,7 +418,7 @@ function Interceptor:receiverequest(request)
if credential ~= nil then
local caller = self.logins:getLoginEntry(credential.login)
if caller ~= nil then
local valid, newsession = self:validateCredential(credential, request)
local valid = self:validateCredential(credential, request)
if valid then
chain = self:validateChain(chain, caller)
if chain ~= nil then
......@@ -437,7 +427,7 @@ function Interceptor:receiverequest(request)
entity = caller.entity,
operation = request.operation_name,
})
self.callerChainOf[running()] = CallChain(chain)
self.callerChainOf[running()] = chain
else
-- return invalid chain exception
setNoPermSysEx(request, loginconst.InvalidChainCode)
......@@ -449,6 +439,8 @@ function Interceptor:receiverequest(request)
end
else
-- credential not valid, try to reset credetial session
local sessions = self.incomingSessions
local newsession = sessions:get(#sessions.map+1)
local challenge, errmsg = caller.pubkey:encrypt(newsession.secret)
if challenge ~= nil then
marshalReset(self, request, newsession.id, challenge)
......@@ -495,7 +487,6 @@ end
local module = {
CallerChain = CallerChain,
Interceptor = Interceptor,
}
......
local table = require "loop.table"
local memoize = table.memoize
local CyclicSets = require "loop.collection.CyclicSets"
local module = {}
function module.LRU(retrieve, maxsize)
if maxsize == nil then maxsize = 128 end
local usage = CyclicSets()
local size = 0
local lastused
local map
map = memoize(function(key)
usage:add(key, lastused)
lastused = key
if size < maxsize then
size = size+1
return retrieve(key)
else
local replacedkey = usage:removefrom(lastused)
local replaced = map[replacedkey]
map[replacedkey] = nil
return retrieve(key, replacedkey, replaced)
end
end)
return map
end
return module
......@@ -16,7 +16,6 @@ LUAMOD= \
openbus.multiplexed \
openbus.util.argcheck \
openbus.util.autotable \
openbus.util.cache \
openbus.util.database \
openbus.util.logger \
openbus.util.messages \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment