Skip to content

Commit

Permalink
Showing 3 changed files with 33 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed

- Fix 3scale Batcher policy failing to cache and report requests containing app ID only [PR #956](https://github.com/3scale/apicast/pull/956), [THREESCALE-1515](https://issues.jboss.org/browse/THREESCALE-1515)
- Auths against the 3scale backend are now retried when using the 3scale batching policy [PR #961](https://github.com/3scale/apicast/pull/961)

## [3.4.0-rc2] - 2018-11-16

18 changes: 18 additions & 0 deletions gateway/src/apicast/backend_client.lua
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ local backend_calls_metrics = require('apicast.metrics.3scale_backend_calls')

local http_proxy = require('resty.http.proxy')
local http_ng_ngx = require('resty.http_ng.backend.ngx')
local http_ng_resty = require('resty.http_ng.backend.resty')
-- resty.http_ng.backend.ngx is using ngx.location.capture, which is available only
-- on rewrite, access and content phases. We need to use cosockets (http_ng default backend)
-- everywhere else (like timers).
@@ -207,6 +208,19 @@ local function format_transactions(reports_batch)
return res
end

-- This is a temporary fix.
-- We know that auths are idempotent so they can be retried safely when there
-- is an error caused by the 3scale backend closing the connection.
-- In the future, we should probably include the logic for retries in the
-- different backends of the http ng libs.
-- This only works with the "resty" backend because the "ngx" has its own logic
-- for retrying.
local function retry_auth(auth_resp, http_backend)
return http_backend == http_ng_resty and
auth_resp.status == 0 and
auth_resp.error == "closed"
end

--- Call authrep (oauth_authrep) on backend.
-- @tparam ?{table,...} query list of query parameters
-- @treturn http_ng.response http response
@@ -236,6 +250,10 @@ function _M:authorize(...)
local auth_uri = auth_path(using_oauth)
local res = call_backend_transaction(self, auth_uri, authorize_options(using_oauth), ...)

if retry_auth(res, self.http_client.backend) then
res = call_backend_transaction(self, auth_uri, authorize_options(using_oauth), ...)
end

inc_metrics('auth', res.status)

return res
14 changes: 14 additions & 0 deletions spec/backend_client_spec.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
local _M = require('apicast.backend_client')
local configuration = require('apicast.configuration')
local http_ng = require 'resty.http_ng'
local http_ng_resty = require 'resty.http_ng.backend.resty'
local ReportsBatch = require 'apicast.policy.3scale_batcher.reports_batch'
local backend_calls_metrics = require 'apicast.metrics.3scale_backend_calls'

@@ -197,6 +198,19 @@ describe('backend client', function()

assert.stub(backend_calls_metrics.report).was_called_with('auth', status)
end)

it('retries when auth return a "closed" error and uses the "resty" http backend', function()
local service = configuration.parse_service({ id = '42' })

local backend_client = assert(_M:new(service, http_ng_resty))
stub(backend_client.http_client, 'get').returns(
{ status = 0, error = 'closed' }
)

backend_client:authorize()

assert.stub(backend_client.http_client.get).was_called(2)
end)
end)

describe('report', function()

0 comments on commit a350650

Please sign in to comment.