Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configurable http_timeout on API requests #70

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Vero::App.init do |config|
config.api_key = "Your Development API key goes here"
config.secret = "Your Development API secret goes here"
end

config.http_timeout = 30 # default timeout per API request is set to 60 (seconds)
end
```

Expand Down
57 changes: 48 additions & 9 deletions lib/vero/api/base_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ module Vero
module Api
module Workers
class BaseAPI
DEFAULT_API_TIMEOUT = 60
ALLOWED_HTTP_METHODS = %i[post put].freeze

attr_accessor :domain
attr_reader :options

def self.perform(domain, options)
caller = new(domain, options)
caller.perform
new(domain, options).perform
end

def initialize(domain, options)
Expand All @@ -27,7 +29,13 @@ def perform
end

def options=(val)
@options = options_with_symbolized_keys(val)
new_options = options_with_symbolized_keys(val)

if (extra_config = new_options.delete(:_config)) && extra_config.is_a?(Hash)
@http_timeout = extra_config[:http_timeout]
end

@options = new_options
end

protected
Expand All @@ -42,20 +50,51 @@ def proxy.<<(message)
end
end

def url; end
def url
"#{@domain}/api/v2/#{api_url}"
end

def http_method
raise NotImplementedError
end

def api_url
raise NotImplementedError
end

def validate!
raise "#{self.class.name}#validate! should be overridden"
end

def request; end
def request
do_request(http_method, url, @options)
end

def do_request(method, a_url, params)
raise ArgumentError, ":method must be one of the follow: #{ALLOWED_HTTP_METHODS.join(', ')}" unless ALLOWED_HTTP_METHODS.include?(method)

rest_client_args = {
method: method,
url: a_url,
timeout: http_timeout
}

if method == :get
rest_client_args.merge!(headers: { params: params })
else
rest_client_args.merge!(payload: JSON.dump(params), headers: { content_type: :json, accept: :json })
end

def request_content_type
{ content_type: :json, accept: :json }
RestClient::Request.execute(
method: method,
url: a_url,
headers: { params: params },
timeout: http_timeout
)
end

def request_params_as_json
JSON.dump(@options)
def http_timeout
@http_timeout || DEFAULT_API_TIMEOUT
end

def options_with_symbolized_keys(val)
Expand Down
8 changes: 4 additions & 4 deletions lib/vero/api/events/track_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module Api
module Workers
module Events
class TrackAPI < BaseAPI
def url
"#{@domain}/api/v2/events/track.json"
def api_url
'events/track.json'
end

def request
RestClient.post(url, request_params_as_json, request_content_type)
def http_method
:post
end

def validate!
Expand Down
8 changes: 4 additions & 4 deletions lib/vero/api/users/edit_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module Api
module Workers
module Users
class EditAPI < BaseAPI
def url
"#{@domain}/api/v2/users/edit.json"
def api_url
'users/edit.json'
end

def request
RestClient.put(url, request_params_as_json, request_content_type)
def http_method
:put
end

def validate!
Expand Down
8 changes: 4 additions & 4 deletions lib/vero/api/users/edit_tags_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module Api
module Workers
module Users
class EditTagsAPI < BaseAPI
def url
"#{@domain}/api/v2/users/tags/edit.json"
def api_url
'users/tags/edit.json'
end

def request
RestClient.put(url, request_params_as_json, request_content_type)
def http_method
:put
end

def validate!
Expand Down
8 changes: 4 additions & 4 deletions lib/vero/api/users/reidentify_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module Api
module Workers
module Users
class ReidentifyAPI < BaseAPI
def url
"#{@domain}/api/v2/users/reidentify.json"
def api_url
'users/reidentify.json'
end

def request
RestClient.put(url, request_params_as_json, request_content_type)
def http_method
:put
end

def validate!
Expand Down
8 changes: 4 additions & 4 deletions lib/vero/api/users/resubscribe_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module Api
module Workers
module Users
class ResubscribeAPI < BaseAPI
def url
"#{@domain}/api/v2/users/resubscribe.json"
def api_url
'users/resubscribe.json'
end

def request
RestClient.post(url, @options)
def http_method
:post
end

def validate!
Expand Down
8 changes: 4 additions & 4 deletions lib/vero/api/users/track_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module Api
module Workers
module Users
class TrackAPI < BaseAPI
def url
"#{@domain}/api/v2/users/track.json"
def api_url
'users/track.json'
end

def request
RestClient.post(url, request_params_as_json, request_content_type)
def http_method
:post
end

def validate!
Expand Down
8 changes: 4 additions & 4 deletions lib/vero/api/users/unsubscribe_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ module Api
module Workers
module Users
class UnsubscribeAPI < BaseAPI
def url
"#{@domain}/api/v2/users/unsubscribe.json"
def api_url
'users/unsubscribe.json'
end

def request
RestClient.post(url, @options)
def http_method
:post
end

def validate!
Expand Down
18 changes: 10 additions & 8 deletions lib/vero/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
module Vero
class Config
attr_writer :domain
attr_accessor :api_key, :secret, :development_mode, :async, :disabled, :logging
attr_accessor :api_key, :secret, :development_mode, :async, :disabled, :logging, :http_timeout

def self.available_attributes
%i[api_key secret development_mode async disabled logging domain]
%i[api_key secret development_mode async disabled logging domain http_timeout]
end

def initialize
Expand All @@ -22,7 +22,8 @@ def config_params
def request_params
{
auth_token: auth_token,
development_mode: development_mode
development_mode: development_mode,
_config: { http_timeout: http_timeout }
}.compact
end

Expand Down Expand Up @@ -53,12 +54,13 @@ def disable_requests!
end

def reset!
self.disabled = false
self.disabled = false
self.development_mode = false
self.async = true
self.logging = false
self.api_key = nil
self.secret = nil
self.async = true
self.logging = false
self.api_key = nil
self.secret = nil
self.http_timeout = nil
end

def update_attributes(attributes = {})
Expand Down
55 changes: 42 additions & 13 deletions spec/lib/api/events/track_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
require 'spec_helper'

describe Vero::Api::Workers::Events::TrackAPI do
subject { Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }) }
let(:payload) do
{
auth_token: 'abcd',
identity: { email: '[email protected]' },
event_name: 'test_event'
}
end

subject { Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', payload) }

it_behaves_like 'a Vero wrapper' do
let(:end_point) { '/api/v2/events/track.json' }
Expand All @@ -16,22 +24,21 @@
subject.options = options
expect { subject.send(:validate!) }.to raise_error(ArgumentError)

options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }
subject.options = options
subject.options = payload
expect { subject.send(:validate!) }.to_not raise_error
end

it 'should raise an error if data is not either nil or a Hash' do
options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event', data: [] }
subject.options = options
payload[:data] = []
subject.options = payload
expect { subject.send(:validate!) }.to raise_error(ArgumentError)

options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event', data: nil }
subject.options = options
payload[:data] = nil
subject.options = payload
expect { subject.send(:validate!) }.to_not raise_error

options = { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event', data: {} }
subject.options = options
payload[:data] = {}
subject.options = payload
expect { subject.send(:validate!) }.to_not raise_error
end

Expand All @@ -49,18 +56,40 @@

describe :request do
it 'should send a JSON request to the Vero API' do
expect(RestClient).to receive(:post).with('https://api.getvero.com/api/v2/events/track.json', { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }.to_json, { content_type: :json, accept: :json })
allow(RestClient).to receive(:post).and_return(200)
expect(RestClient::Request).to(
receive(:execute).with(
method: :post,
url: 'https://api.getvero.com/api/v2/events/track.json',
payload: { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }.to_json,
headers: { content_type: :json, accept: :json },
timeout: 60
)
)
allow(RestClient::Request).to receive(:execute).and_return(200)
subject.send(:request)
end

it 'should allow configurable timeout' do
expect(RestClient::Request).to(
receive(:execute).with(
method: :post,
url: 'https://api.getvero.com/api/v2/events/track.json',
payload: { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' }.to_json,
headers: { content_type: :json, accept: :json },
timeout: 30
)
)
allow(RestClient::Request).to receive(:execute).and_return(200)
Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', payload.merge(_config: { http_timeout: 30 })).send(:request)
end
end
end

describe 'integration test' do
it 'should not raise any errors' do
obj = Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', { auth_token: 'abcd', identity: { email: '[email protected]' }, event_name: 'test_event' })
obj = Vero::Api::Workers::Events::TrackAPI.new('https://api.getvero.com', payload)

allow(RestClient).to receive(:post).and_return(200)
allow(RestClient::Request).to receive(:execute).and_return(200)
expect { obj.perform }.to_not raise_error
end
end
Expand Down
24 changes: 20 additions & 4 deletions spec/lib/api/users/edit_api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
require 'spec_helper'

describe Vero::Api::Workers::Users::EditAPI do
subject { Vero::Api::Workers::Users::EditAPI.new('https://api.getvero.com', { auth_token: 'abcd', email: '[email protected]', changes: { email: '[email protected]' } }) }
let(:payload) do
{
auth_token: 'abcd',
email: '[email protected]',
changes: { email: '[email protected]' }
}
end

subject { Vero::Api::Workers::Users::EditAPI.new('https://api.getvero.com', payload) }

it_behaves_like 'a Vero wrapper' do
let(:end_point) { '/api/v2/users/edit.json' }
Expand All @@ -19,15 +27,23 @@

describe :request do
it 'should send a request to the Vero API' do
expect(RestClient).to receive(:put).with('https://api.getvero.com/api/v2/users/edit.json', { auth_token: 'abcd', email: '[email protected]', changes: { email: '[email protected]' } }.to_json, { content_type: :json, accept: :json })
allow(RestClient).to receive(:put).and_return(200)
expect(RestClient::Request).to(
receive(:execute).with(
method: :put,
url: 'https://api.getvero.com/api/v2/users/edit.json',
payload: { auth_token: 'abcd', email: '[email protected]', changes: { email: '[email protected]' } }.to_json,
headers: { content_type: :json, accept: :json },
timeout: 60
)
)
allow(RestClient::Request).to receive(:execute).and_return(200)
subject.send(:request)
end
end

describe 'integration test' do
it 'should not raise any errors' do
allow(RestClient).to receive(:put).and_return(200)
allow(RestClient::Request).to receive(:execute).and_return(200)
expect { subject.perform }.to_not raise_error
end
end
Expand Down
Loading
Loading