Skip to content

Commit

Permalink
[backend] extract backend client
Browse files Browse the repository at this point in the history
  • Loading branch information
mikz committed Mar 14, 2017
1 parent f44a377 commit 5efbcd4
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 34 deletions.
81 changes: 81 additions & 0 deletions apicast/src/backend_client.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
local setmetatable = setmetatable
local concat = table.concat

local http_ng = require('resty.http_ng')
local user_agent = require('user_agent')
local resty_url = require('resty.url')

local _M = {

}

local mt = { __index = _M }

function _M.new(service, http_client)
local endpoint = service.backend.endpoint or ngx.var.backend_endpoint
local service_id = service.id

if not endpoint then
ngx.log(ngx.WARN, 'service ', service_id, ' does not have backend endpoint configured')
end

local authentication = { service_id = service_id }

if service.backend_authentication.type then
authentication[service.backend_authentication.type] = service.backend_authentication.value
end

local backend = resty_url.split(endpoint)

local client = http_ng.new{
backend = http_client,
options = {
headers = {
user_agent = user_agent(),
host = service.backend.host or backend[4]
},
ssl = { verify = false }
}
}

return setmetatable({
version = service.backend_version,
endpoint = endpoint,
service_id = service_id,
authentication = authentication,
http_client = client
}, mt)
end

function _M:authrep(...)
local version = self.version
local http_client = self.http_client

if not version or not http_client then
return nil, 'not initialized'
end

local endpoint = self.endpoint

if not endpoint then
return nil, 'missing endpoint'
end

local auth_uri = version == 'oauth' and 'oauth_authrep.xml' or 'authrep.xml'

local args = { self.authentication, ... }

for i=1, #args do
args[i] = ngx.encode_args(args[i])
end

local url = resty_url.join(endpoint, '/transactions/', auth_uri, '?', concat(args, '&'))

local res = http_client.get(url)

ngx.log(ngx.INFO, 'backend client uri: ', url, ' ok: ', res.ok, ' status: ', res.status, ' body: ', res.body)

return res
end

return _M
49 changes: 15 additions & 34 deletions apicast/src/proxy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@ local tonumber = tonumber
local setmetatable = setmetatable
local encode_args = ngx.encode_args
local resty_resolver = require 'resty.resolver'
local http_ng = require('resty.http_ng')
local user_agent = require 'user_agent'
local semaphore = require('ngx.semaphore')
local backend_client = require('backend_client')
local timers = semaphore.new(tonumber(env.get('APICAST_CONCURRENCY') or 512))

local empty = {}
Expand All @@ -36,18 +35,9 @@ local mt = {
__index = _M
}

function _M.new(configuration, http_client)
local client = http_ng.new{
backend = http_client,
options = {
headers = { ['User-Agent'] = user_agent() },
ssl = { verify = false }
}
}

function _M.new(configuration)
return setmetatable({
configuration = assert(configuration, 'missing proxy configuration'),
http_client = client
configuration = assert(configuration, 'missing proxy configuration')
}, mt)
end

Expand Down Expand Up @@ -349,6 +339,8 @@ function _M:access(service)
credentials[i] = nil
end

ngx.ctx.usage = params
ngx.ctx.credentials = credentials
credentials = encode_args(credentials)

ngx.var.credentials = credentials
Expand All @@ -372,11 +364,11 @@ function _M:access(service)
end


local function request_logs_encoded_data()
local function request_logs_data()
local request_log = {}

if not request_logs and not response_codes then
return ''
return {}
end

if request_logs then
Expand All @@ -393,13 +385,15 @@ local function request_logs_encoded_data()
request_log["log[code]"] = ngx.var.status
end

return ngx.encode_args(request_log)
return request_log
end

local function post_action(_, http_client, cached_key, uri, options)
local res = util.timer('backend post_action', http_client.get, uri, options)
local function request_logs_encoded_data()
return ngx.encode_args(request_logs_data())
end

ngx.log(ngx.INFO, 'finished post action call: ', uri, ' status: ', res.status)
local function post_action(_, cached_key, backend, ...)
local res = util.timer('backend post_action', backend.authrep, backend, ...)

if not res.ok or res.status ~= 200 then
local api_keys = ngx.shared.api_keys
Expand Down Expand Up @@ -431,18 +425,7 @@ function _M:post_action(force)

local service_id = ngx.var.service_id
local service = ngx.ctx.service or self.configuration:find_by_id(service_id)
local auth_uri = service.backend_version == 'oauth' and 'oauth_authrep.xml' or 'authrep.xml'

local endpoint = service.backend.endpoint or ngx.var.backend_endpoint
if not endpoint then
ngx.log(ngx.WARN, 'service ', service_id, ' does not have backend endpoint configured')
return
end

local backend = resty_url.split(endpoint)

local service_args = ngx.encode_args({ [service.backend_authentication.type or ''] = service.backend_authentication.value, service_id = service_id })
local uri = resty_url.join(endpoint, '/transactions/', auth_uri) .."?" .. service_args .. '&' .. ngx.var.usage ..'&' .. ngx.var.credentials .. "&" .. request_logs_encoded_data()
local backend = assert(backend_client.new(service), 'missing backend')

local ok, err

Expand All @@ -455,9 +438,7 @@ function _M:post_action(force)
if ok then
-- TODO: try to do this in different phase and use semaphore to limit number of background threads
-- TODO: Also it is possible to use sets in shared memory to enqueue work
ngx.timer.at(0, post_action, self.http_client, cached_key, uri, {
headers = { host = service.backend.host or backend[4] or ngx.var.backend_host }
})
ngx.timer.at(0, post_action, cached_key, backend, ngx.ctx.usage, ngx.ctx.credentials, request_logs_data())
else
ngx.log(ngx.ERR, 'failed to acquire timer: ', err)
end
Expand Down

0 comments on commit 5efbcd4

Please sign in to comment.