Split token refresh and retry policy into different middlewares. Corrected MethodTemplate.

This commit is contained in:
Nick Lebedev 2015-07-28 19:32:30 +03:00
Родитель d925888aae
Коммит 980a213211
6 изменённых файлов: 73 добавлений и 40 удалений

Просмотреть файл

@ -1,4 +1,5 @@
@using System.Linq;
@using System
@using System.Linq;
@using Microsoft.Rest.Generator.ClientModel
@using Microsoft.Rest.Generator.Ruby.TemplateModels
@inherits Microsoft.Rest.Generator.Template<Microsoft.Rest.Generator.Ruby.MethodTemplateModel>
@ -28,8 +29,11 @@ def @(Model.Name)(@(Model.MethodParameterDeclaration))
@(Model.RemoveDuplicateForwardSlashes("url"))
@EmptyLine
@* TODO: add proper references to @client *@
connection = Faraday.new(:url => url) do |faraday|
faraday.use RetryPolicyMiddleware, times: 3, retry: 0.02, credentials: @(Model.ClientReference).credentials
faraday.use TokenRefreshMiddleware, credentials: @(Model.ClientReference).credentials
faraday.use :cookie_jar
faraday.adapter Faraday.default_adapter
end
@ -68,7 +72,10 @@ def @(Model.Name)(@(Model.MethodParameterDeclaration))
promise = Concurrent::Promise.new do
connection.put do |request|
request.headers = request_headers
request.body = request_content
@if (Model.RequestBody != null)
{
@:request.body = request_content
}
end
end
@ -80,17 +87,18 @@ def @(Model.Name)(@(Model.MethodParameterDeclaration))
@if (Model.DefaultResponse != null)
{
@:error_model = JSON.load(response_content)
@:fail @(Model.OperationExceptionTypeString).new(request_content, http_response, error_model)
@:fail @(Model.OperationExceptionTypeString).new(http_response, http_response, error_model)
}
else
{
@:fail @(Model.OperationExceptionTypeString).new(request_content, http_response)
@:fail @(Model.OperationExceptionTypeString).new(http_response, http_response)
}
end
@EmptyLine
@* TODO: add propert request object into HttpOperationResponse and HttpOperationException *@
# Create Result
result = @(Model.OperationResponseReturnTypeString).new(request_content, http_response)
result = @(Model.OperationResponseReturnTypeString).new(http_response, http_response)
@Model.InitializeResponseBody
@foreach (var responsePair in Model.Responses.Where(r => r.Value != null && r.Value.IsSerializable()))

Просмотреть файл

@ -28,9 +28,9 @@ module MsRestAzure
fail CloudError if azure_response.nil?
fail CloudError if get_operation_block.nil?
if (azure_response.response.code != "200" &&
azure_response.response.code != "201" &&
azure_response.response.code != "202")
status_code = azure_response.response.status
if (status_code != 200 && status_code != 201 && status_code != 202)
fail CloudError
end

Просмотреть файл

@ -34,10 +34,10 @@ module MsRestAzure
if (!@resource.nil? && @resource.respond_to?(:properties) && @resource.properties.respond_to?(:provisioning_state) && !@resource.properties.provisioning_state.nil?)
@status = @resource.properties.provisioning_state
else
case @response.code
when "202"
case @response.status
when 202
@status = AsyncOperationStatus::IN_PROGRESS_STATUS
when "200", "201", "204"
when 200, 201, 204
@status = AsyncOperationStatus::SUCCESS_STATUS
else
@status = AsyncOperationStatus::FAILED_STATUS

Просмотреть файл

@ -15,6 +15,7 @@ require 'ms_rest/serialization.rb'
require 'ms_rest/http_operation_response'
require 'ms_rest/http_operation_exception'
require 'ms_rest/retry_policy_middleware'
require 'ms_rest/token_refresh_middleware'
require 'ms_rest/service_client'
module MsRest; end

Просмотреть файл

@ -3,7 +3,7 @@
module MsRest
#
# Class whcih handles retry and token renewal stuff.
# Class which handles retry policy.
#
class RetryPolicyMiddleware < Faraday::Response::Middleware
#
@ -19,25 +19,6 @@ module MsRest
super(app)
end
#
# Verifies whether given response is about authentication token expiration.
# @param response [Net::HTTPResponse] http response to verify.
#
# @return [Bool] true if response is about authentication token expiration, false otherwise.
def is_token_expired_response(response)
return false unless response.status == 401
begin
response_body = JSON.load(response.body)
error_code = response_body['error']['code']
error_message = response_body['error']['message']
rescue Exception => e
return false
end
return (error_code == 'AuthenticationFailed' && (error_message.start_with?('The access token expiry') || (error_message.start_with?('The access token is missing or invalid'))))
end
#
# Performs request and response processing.
#
@ -49,17 +30,9 @@ module MsRest
request_env[:body] = request_body
@app.call(request_env).on_complete do |response_env|
if (is_token_expired_response(response_env))
@credentials.acquire_token()
@credentials.sign_request(request_env)
sleep @delay
fail
end
status_code = response_env.status
if (status_code == 408 || (status_code >= 500 && status_code != 501 && status_code != 505))
if (status_code == 408 || status_code == 401 || (status_code >= 500 && status_code != 501 && status_code != 505))
sleep @delay
fail
end

Просмотреть файл

@ -0,0 +1,51 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
module MsRest
#
# Class which handles token renewal.
#
class TokenRefreshMiddleware < Faraday::Response::Middleware
#
# Initializes a new instance of the TokenRefreshMiddleware class.
#
def initialize(app, options = nil)
fail ArgumentError, 'options can\'t be nil' if options.nil?
fail ArgumentError, 'options must contain credentials object' if options[:credentials].nil?
@credentials = options[:credentials]
super(app)
end
#
# Verifies whether given response is about authentication token expiration.
# @param response [Net::HTTPResponse] http response to verify.
#
# @return [Bool] true if response is about authentication token expiration, false otherwise.
def is_token_expired_response(response)
return false unless response.status == 401
begin
response_body = JSON.load(response.body)
error_code = response_body['error']['code']
error_message = response_body['error']['message']
rescue Exception => e
return false
end
return (error_code == 'AuthenticationFailed' && (error_message.start_with?('The access token expiry') || (error_message.start_with?('The access token is missing or invalid'))))
end
#
# Performs request and response processing.
#
def call(request_env)
@app.call(request_env).on_complete do |response_env|
if (is_token_expired_response(response_env))
@credentials.acquire_token()
@credentials.sign_request(request_env)
end
end
end
end
end