From 85e143c5d499b95512f74ed6b59fe2f1b463158a Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Wed, 16 Aug 2023 18:58:06 +0200 Subject: [PATCH 01/19] Base design --- lib/datadog_api_client/api_client.rb | 42 +++++++++++++++++++++---- lib/datadog_api_client/configuration.rb | 17 +++++++--- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/lib/datadog_api_client/api_client.rb b/lib/datadog_api_client/api_client.rb index 44686f9f0b7d..44099102824d 100644 --- a/lib/datadog_api_client/api_client.rb +++ b/lib/datadog_api_client/api_client.rb @@ -55,6 +55,8 @@ def self.default # the data deserialized from response body (could be nil), response status code and response headers. def call_api(http_method, path, opts = {}) request = build_request(http_method, path, opts) + attempt = 0 + loop do if opts[:stream_body] tempfile = nil encoding = nil @@ -107,10 +109,16 @@ def call_api(http_method, path, opts = {}) body = gzip.inflate(body) gzip.close end - fail APIError.new(:code => response.code, - :response_headers => response.headers, - :response_body => body), - response.message + if should_retry(attempt, @config.retry_config, response.code) + sleep calculate_retry_interval(response, @config.retry_config, attempt, @config.timeout) + attempt += 1 + break + else + fail APIError.new(:code => response.code, + :response_headers => response.headers, + :response_body => body), + response.message + end end end @@ -121,6 +129,28 @@ def call_api(http_method, path, opts = {}) end return data, response.code, response.headers end + end + + # Check if an http request should be retried + def should_retry(attempt, retry_config, http_code) + (http_code == 429 || http_code >= 500) && retry_config["maxRetries"] > attempt && retry_config["enableRetry"] + end + + # Calculate the sleep interval between 2 retry attempts + def calculate_retry_interval(response, retry_config, attempt, timeout) + backoff_base = retry_config["backoffBase"] + backoff_multiplier = retry_config["backoffMultiplier"] + reset_header = response.headers['X-Ratelimit-Reset'] + if !reset_header.nil? && !reset_header.empty? + sleep_time = reset_header.to_i + else + sleep_time = (backoff_multiplier**attempt) * backoff_base + if timeout > 0 + sleep_time = [timeout, sleep_time].min + end + end + sleep_time + end # Build the HTTP request # @@ -443,7 +473,7 @@ def build_collection_param(param, collection_format) # @param [Object] default The default value, if not found # @return [Object] The value found, or default # @!visibility private - def get_attribute_from_path(obj, attribute_path, default=nil) + def get_attribute_from_path(obj, attribute_path, default = nil) for attr in attribute_path.split(".") do case obj when Hash @@ -531,4 +561,4 @@ def message msg end end -end \ No newline at end of file +end diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index 8bce152579a8..4babb7ae1090 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -149,6 +149,9 @@ class Configuration # Password for proxy server authentication attr_accessor :http_proxypass + # Configuration for retry behavior + attr_accessor :retry_config + def initialize @scheme = 'https' @host = 'api.datadoghq.com' @@ -159,6 +162,7 @@ def initialize @server_operation_variables = {} @api_key = {} @api_key_prefix = {} + @retry_config = {} @timeout = nil @client_side_validation = true @verify_ssl = true @@ -221,6 +225,10 @@ def initialize @server_variables[:site] = ENV['DD_SITE'] if ENV.key? 'DD_SITE' @api_key['apiKeyAuth'] = ENV['DD_API_KEY'] if ENV.key? 'DD_API_KEY' @api_key['appKeyAuth'] = ENV['DD_APP_KEY'] if ENV.key? 'DD_APP_KEY' + @retry_config['enableRetry'] = false + @retry_config['backoffBase'] = 2 + @retry_config['backoffMultiplier'] = 2 + @retry_config['maxRetries'] = 3 yield(self) if block_given? end @@ -416,7 +424,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -468,7 +476,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -520,7 +528,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -572,5 +580,4 @@ def to_hash self.data end end - -end \ No newline at end of file +end From ea06a36d1a51ea1d4db0d311aa2256a3087c7b66 Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Thu, 17 Aug 2023 20:32:52 +0200 Subject: [PATCH 02/19] add_test --- spec/retry_spec.rb | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 spec/retry_spec.rb diff --git a/spec/retry_spec.rb b/spec/retry_spec.rb new file mode 100644 index 000000000000..3cecc7147c46 --- /dev/null +++ b/spec/retry_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe 'logs_archive retry test' do + before do + DatadogAPIClient.configure { |c| c.retry_config["enableRetry"] = true} + @api_instance = DatadogAPIClient::V2::LogsArchivesAPI.new + @base_path = @api_instance.api_client.build_request_url('') + @body = DatadogAPIClient::V2::LogsArchiveCreateRequest.new + + # Stub the sleep method to sleep for 0 seconds + allow_any_instance_of(Kernel).to receive(:sleep).with(1).and_return(nil) + end + it `should retry the the action 3 times` do + fixture = File.read('spec/fixtures/logs_archive_unknown_nested_oneof.json') + stub_request(:post, "#{@base_path}api/v2/logs/config/archives") + .to_return( + {:body => fixture, :headers => [{"Content-Type": "application/json"},{"X-Ratelimit-Reset" : "1"}], :status => 429}, + {:body => fixture, :headers => [{"Content-Type": "application/json"},{"X-Ratelimit-Reset" : "1"}], :status => 429}, + {:body => fixture, :headers => [{"Content-Type": "application/json"},{"X-Ratelimit-Reset" : "1"}], :status => 429}, + {:body => fixture, :headers => [{"Content-Type": "application/json"}], :status => 299} + ) + + data = @api_instance.create_logs_archive(@body) + + expect(webmock).to have_requested(:post, "#{@base_path}api/v2/logs/config/archives").times(3) + expect(calculate_retry_interval.call()).to eq(1).times(3) + + expect(data).to be_a DatadogAPIClient::V2::LogsArchive + expect(data.data.attributes._unparsed).to be true + expect(data.data.attributes.destination.data[:type]).to eq "A non existent destination" + end +end From c753dd3f72cd396d872c8dbf63908a9a13c91fde Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Fri, 18 Aug 2023 14:17:56 +0200 Subject: [PATCH 03/19] adjust test --- spec/retry_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/retry_spec.rb b/spec/retry_spec.rb index 3cecc7147c46..b449550bbe81 100644 --- a/spec/retry_spec.rb +++ b/spec/retry_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +# require 'spec_helper' describe 'logs_archive retry test' do before do - DatadogAPIClient.configure { |c| c.retry_config["enableRetry"] = true} + DatadogAPIClient.configure { |c| c.retry_config["enableRetry"] = true } @api_instance = DatadogAPIClient::V2::LogsArchivesAPI.new @base_path = @api_instance.api_client.build_request_url('') @body = DatadogAPIClient::V2::LogsArchiveCreateRequest.new @@ -10,13 +10,13 @@ # Stub the sleep method to sleep for 0 seconds allow_any_instance_of(Kernel).to receive(:sleep).with(1).and_return(nil) end - it `should retry the the action 3 times` do + it 'should retry the action 3 times' do fixture = File.read('spec/fixtures/logs_archive_unknown_nested_oneof.json') stub_request(:post, "#{@base_path}api/v2/logs/config/archives") .to_return( - {:body => fixture, :headers => [{"Content-Type": "application/json"},{"X-Ratelimit-Reset" : "1"}], :status => 429}, - {:body => fixture, :headers => [{"Content-Type": "application/json"},{"X-Ratelimit-Reset" : "1"}], :status => 429}, - {:body => fixture, :headers => [{"Content-Type": "application/json"},{"X-Ratelimit-Reset" : "1"}], :status => 429}, + {:body => fixture, :headers => [{"Content-Type": "application/json"}, {"X-Ratelimit-Reset" => "1"}], :status => 429}, + {:body => fixture, :headers => [{"Content-Type": "application/json"}, {"X-Ratelimit-Reset" => "1"}], :status => 429}, + {:body => fixture, :headers => [{"Content-Type": "application/json"}, {"X-Ratelimit-Reset" => "1"}], :status => 429}, {:body => fixture, :headers => [{"Content-Type": "application/json"}], :status => 299} ) From 44b3f2ed0f4734c8662bce308ed1c60b3518f16d Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Fri, 18 Aug 2023 15:15:25 +0200 Subject: [PATCH 04/19] handle nil --- lib/datadog_api_client/api_client.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/datadog_api_client/api_client.rb b/lib/datadog_api_client/api_client.rb index 44099102824d..83791df5b276 100644 --- a/lib/datadog_api_client/api_client.rb +++ b/lib/datadog_api_client/api_client.rb @@ -111,7 +111,7 @@ def call_api(http_method, path, opts = {}) end if should_retry(attempt, @config.retry_config, response.code) sleep calculate_retry_interval(response, @config.retry_config, attempt, @config.timeout) - attempt += 1 + attempt = attempt + 1 break else fail APIError.new(:code => response.code, @@ -145,7 +145,7 @@ def calculate_retry_interval(response, retry_config, attempt, timeout) sleep_time = reset_header.to_i else sleep_time = (backoff_multiplier**attempt) * backoff_base - if timeout > 0 + if timeout && timeout > 0 sleep_time = [timeout, sleep_time].min end end From 444fe338f13801aa48be05ad092b06f5552370b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Herv=C3=A9?= Date: Fri, 18 Aug 2023 16:05:24 +0200 Subject: [PATCH 05/19] Fix tests --- lib/datadog_api_client/api_client.rb | 124 +++++++++++++-------------- spec/retry_spec.rb | 17 ++-- 2 files changed, 70 insertions(+), 71 deletions(-) diff --git a/lib/datadog_api_client/api_client.rb b/lib/datadog_api_client/api_client.rb index 83791df5b276..c3bdf5a46dad 100644 --- a/lib/datadog_api_client/api_client.rb +++ b/lib/datadog_api_client/api_client.rb @@ -57,78 +57,78 @@ def call_api(http_method, path, opts = {}) request = build_request(http_method, path, opts) attempt = 0 loop do - if opts[:stream_body] - tempfile = nil - encoding = nil - - response = request.perform do | chunk | - unless tempfile - content_disposition = chunk.http_response.header['Content-Disposition'] - if content_disposition && content_disposition =~ /filename=/i - filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] - prefix = sanitize_filename(filename) - else - prefix = 'download-' - end - prefix = prefix + '-' unless prefix.end_with?('-') - unless encoding - encoding = chunk.encoding + if opts[:stream_body] + tempfile = nil + encoding = nil + + response = request.perform do | chunk | + unless tempfile + content_disposition = chunk.http_response.header['Content-Disposition'] + if content_disposition && content_disposition =~ /filename=/i + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] + prefix = sanitize_filename(filename) + else + prefix = 'download-' + end + prefix = prefix + '-' unless prefix.end_with?('-') + unless encoding + encoding = chunk.encoding + end + tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) + @tempfile = tempfile end - tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) - @tempfile = tempfile + chunk.force_encoding(encoding) + tempfile.write(chunk) end - chunk.force_encoding(encoding) - tempfile.write(chunk) - end - if tempfile - tempfile.close - @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ - "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ - "will be deleted automatically with GC. It's also recommended to delete the temp file "\ - "explicitly with `tempfile.delete`" + if tempfile + tempfile.close + @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ + "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ + "will be deleted automatically with GC. It's also recommended to delete the temp file "\ + "explicitly with `tempfile.delete`" + end + else + response = request.perform end - else - response = request.perform - end - if @config.debugging - @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" - end + if @config.debugging + @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" + end - unless response.success? - if response.request_timeout? - fail APIError.new('Connection timed out') - elsif response.code == 0 - # Errors from libcurl will be made visible here - fail APIError.new(:code => 0, - :message => response.return_message) - else - body = response.body - if response.headers['Content-Encoding'].eql?('gzip') && !(body.nil? || body.empty?) then - gzip = Zlib::Inflate.new(Zlib::MAX_WBITS + 16) - body = gzip.inflate(body) - gzip.close - end - if should_retry(attempt, @config.retry_config, response.code) - sleep calculate_retry_interval(response, @config.retry_config, attempt, @config.timeout) - attempt = attempt + 1 - break + unless response.success? + if response.request_timeout? + fail APIError.new('Connection timed out') + elsif response.code == 0 + # Errors from libcurl will be made visible here + fail APIError.new(:code => 0, + :message => response.return_message) else - fail APIError.new(:code => response.code, - :response_headers => response.headers, - :response_body => body), - response.message + body = response.body + if response.headers['Content-Encoding'].eql?('gzip') && !(body.nil? || body.empty?) then + gzip = Zlib::Inflate.new(Zlib::MAX_WBITS + 16) + body = gzip.inflate(body) + gzip.close + end + if should_retry(attempt, @config.retry_config, response.code) + sleep calculate_retry_interval(response, @config.retry_config, attempt, @config.timeout) + attempt = attempt + 1 + next + else + fail APIError.new(:code => response.code, + :response_headers => response.headers, + :response_body => body), + response.message + end end end - end - if opts[:return_type] - data = deserialize(opts[:api_version], response, opts[:return_type]) - else - data = nil + if opts[:return_type] + data = deserialize(opts[:api_version], response, opts[:return_type]) + else + data = nil + end + return data, response.code, response.headers end - return data, response.code, response.headers - end end # Check if an http request should be retried diff --git a/spec/retry_spec.rb b/spec/retry_spec.rb index b449550bbe81..9f3dcb05cb65 100644 --- a/spec/retry_spec.rb +++ b/spec/retry_spec.rb @@ -1,4 +1,5 @@ -# require 'spec_helper' +require 'spec_helper' +require 'webmock/rspec' describe 'logs_archive retry test' do before do @@ -14,19 +15,17 @@ fixture = File.read('spec/fixtures/logs_archive_unknown_nested_oneof.json') stub_request(:post, "#{@base_path}api/v2/logs/config/archives") .to_return( - {:body => fixture, :headers => [{"Content-Type": "application/json"}, {"X-Ratelimit-Reset" => "1"}], :status => 429}, - {:body => fixture, :headers => [{"Content-Type": "application/json"}, {"X-Ratelimit-Reset" => "1"}], :status => 429}, - {:body => fixture, :headers => [{"Content-Type": "application/json"}, {"X-Ratelimit-Reset" => "1"}], :status => 429}, - {:body => fixture, :headers => [{"Content-Type": "application/json"}], :status => 299} + {:body => fixture, :headers => {"Content-Type": "application/json", "X-Ratelimit-Reset" => "1"}, :status => 429}, + {:body => fixture, :headers => {"Content-Type": "application/json", "X-Ratelimit-Reset" => "1"}, :status => 429}, + {:body => fixture, :headers => {"Content-Type": "application/json", "X-Ratelimit-Reset" => "1"}, :status => 429}, + {:body => fixture, :headers => {"Content-Type": "application/json"}, :status => 299} ) data = @api_instance.create_logs_archive(@body) - expect(webmock).to have_requested(:post, "#{@base_path}api/v2/logs/config/archives").times(3) - expect(calculate_retry_interval.call()).to eq(1).times(3) + expect(WebMock).to have_requested(:post, "#{@base_path}api/v2/logs/config/archives").times(4) + #expect(@api_instance.api_client.calculate_retry_interval.call()).to eq(1).times(3) expect(data).to be_a DatadogAPIClient::V2::LogsArchive - expect(data.data.attributes._unparsed).to be true - expect(data.data.attributes.destination.data[:type]).to eq "A non existent destination" end end From fceb17510284a548121b916a5279fdb8b81553ab Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Fri, 18 Aug 2023 18:45:14 +0200 Subject: [PATCH 06/19] add testing sleep time without actually sleeping --- spec/retry_spec.rb | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/spec/retry_spec.rb b/spec/retry_spec.rb index 9f3dcb05cb65..fe44c35fb2a6 100644 --- a/spec/retry_spec.rb +++ b/spec/retry_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require 'webmock/rspec' describe 'logs_archive retry test' do before do @@ -7,11 +6,9 @@ @api_instance = DatadogAPIClient::V2::LogsArchivesAPI.new @base_path = @api_instance.api_client.build_request_url('') @body = DatadogAPIClient::V2::LogsArchiveCreateRequest.new - - # Stub the sleep method to sleep for 0 seconds - allow_any_instance_of(Kernel).to receive(:sleep).with(1).and_return(nil) + allow_any_instance_of(DatadogAPIClient::APIClient).to receive(:sleep) end - it 'should retry the action 3 times' do + it 'should retry 3 times and sleep for the value of X-Ratelimit-Reset' do fixture = File.read('spec/fixtures/logs_archive_unknown_nested_oneof.json') stub_request(:post, "#{@base_path}api/v2/logs/config/archives") .to_return( @@ -20,12 +17,25 @@ {:body => fixture, :headers => {"Content-Type": "application/json", "X-Ratelimit-Reset" => "1"}, :status => 429}, {:body => fixture, :headers => {"Content-Type": "application/json"}, :status => 299} ) - data = @api_instance.create_logs_archive(@body) - + expect(@api_instance::api_client).to have_received(:sleep).exactly(3).times.with(1) expect(WebMock).to have_requested(:post, "#{@base_path}api/v2/logs/config/archives").times(4) - #expect(@api_instance.api_client.calculate_retry_interval.call()).to eq(1).times(3) + end + + it 'should retry 3 times and sleep for 2,4,8 seconds' do + fixture = File.read('spec/fixtures/logs_archive_unknown_nested_oneof.json') + stub_request(:post, "#{@base_path}api/v2/logs/config/archives") + .to_return( + {:body => fixture, :headers => {"Content-Type": "application/json"}, :status => 500}, + {:body => fixture, :headers => {"Content-Type": "application/json"}, :status => 500}, + {:body => fixture, :headers => {"Content-Type": "application/json"}, :status => 500}, + {:body => fixture, :headers => {"Content-Type": "application/json"}, :status => 299} + ) - expect(data).to be_a DatadogAPIClient::V2::LogsArchive + data = @api_instance.create_logs_archive(@body) + expect(@api_instance::api_client).to have_received(:sleep).exactly(1).times.with(2) + expect(@api_instance::api_client).to have_received(:sleep).exactly(1).times.with(4) + expect(@api_instance::api_client).to have_received(:sleep).exactly(1).times.with(8) + expect(WebMock).to have_requested(:post, "#{@base_path}api/v2/logs/config/archives").times(4) end end From d06917796ebf9501af2f27b38bef6ac358a74448 Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Fri, 18 Aug 2023 18:58:26 +0200 Subject: [PATCH 07/19] Add documentation --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 829554c53b50..f1ce2d7fd960 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,25 @@ api_instance.list_incidents_with_pagination() do |incident| end ``` +### Retry + +To enable the client to retry when rate limited (status 429) or status 500 and above: + +```ruby +config = DatadogAPIClient::Configuration.new +config.retry_config['enableRetry'] = true +client = DatadogAPIClient::APIClient.new(config) +``` +The interval between 2 retry attempts will be the value of the `x-ratelimit-reset` response header when available. +If not, it will be : +```ruby +(retry_config['backoffMultiplier'] ** current_retry_count) * retry_config['backoffBase'] +``` +The maximum number of retry attempts is `3` by default and can be modified with +```ruby +retry_config['maxRetries'] +``` + ## Documentation If you are interested in general documentation for all public Datadog API endpoints, checkout the [general documentation site][api docs]. From 45cf3ce7639fdf45a42a81c522170ce38d07be7c Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Mon, 21 Aug 2023 15:03:38 +0200 Subject: [PATCH 08/19] change code generator --- .../src/generator/templates/api_client.j2 | 136 +++++++++++------- .../src/generator/templates/configuration.j2 | 8 ++ 2 files changed, 91 insertions(+), 53 deletions(-) diff --git a/.generator/src/generator/templates/api_client.j2 b/.generator/src/generator/templates/api_client.j2 index 77dde98a8ced..20a45516da3d 100644 --- a/.generator/src/generator/templates/api_client.j2 +++ b/.generator/src/generator/templates/api_client.j2 @@ -44,71 +44,101 @@ module {{ module_name }} # the data deserialized from response body (could be nil), response status code and response headers. def call_api(http_method, path, opts = {}) request = build_request(http_method, path, opts) - if opts[:stream_body] - tempfile = nil - encoding = nil - - response = request.perform do | chunk | - unless tempfile - content_disposition = chunk.http_response.header['Content-Disposition'] - if content_disposition && content_disposition =~ /filename=/i - filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] - prefix = sanitize_filename(filename) - else - prefix = 'download-' - end - prefix = prefix + '-' unless prefix.end_with?('-') - unless encoding - encoding = chunk.encoding + attempt = 0 + loop do + if opts[:stream_body] + tempfile = nil + encoding = nil + + response = request.perform do | chunk | + unless tempfile + content_disposition = chunk.http_response.header['Content-Disposition'] + if content_disposition && content_disposition =~ /filename=/i + filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1] + prefix = sanitize_filename(filename) + else + prefix = 'download-' + end + prefix = prefix + '-' unless prefix.end_with?('-') + unless encoding + encoding = chunk.encoding + end + tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) + @tempfile = tempfile end - tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding) - @tempfile = tempfile + chunk.force_encoding(encoding) + tempfile.write(chunk) + end + if tempfile + tempfile.close + @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ + "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ + "will be deleted automatically with GC. It's also recommended to delete the temp file "\ + "explicitly with `tempfile.delete`" end - chunk.force_encoding(encoding) - tempfile.write(chunk) + else + response = request.perform end - if tempfile - tempfile.close - @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\ - "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\ - "will be deleted automatically with GC. It's also recommended to delete the temp file "\ - "explicitly with `tempfile.delete`" + + if @config.debugging + @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" end - else - response = request.perform - end - if @config.debugging - @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n" - end + unless response.success? + if response.request_timeout? + fail APIError.new('Connection timed out') + elsif response.code == 0 + # Errors from libcurl will be made visible here + fail APIError.new(:code => 0, + :message => response.return_message) + else + body = response.body + if response.headers['Content-Encoding'].eql?('gzip') && !(body.nil? || body.empty?) then + gzip = Zlib::Inflate.new(Zlib::MAX_WBITS + 16) + body = gzip.inflate(body) + gzip.close + end + if should_retry(attempt, @config.retry_config, response.code) + sleep calculate_retry_interval(response, @config.retry_config, attempt, @config.timeout) + attempt = attempt + 1 + next + else + fail APIError.new(:code => response.code, + :response_headers => response.headers, + :response_body => body), + response.message + end + end + end - unless response.success? - if response.request_timeout? - fail APIError.new('Connection timed out') - elsif response.code == 0 - # Errors from libcurl will be made visible here - fail APIError.new(:code => 0, - :message => response.return_message) + if opts[:return_type] + data = deserialize(opts[:api_version], response, opts[:return_type]) else - body = response.body - if response.headers['Content-Encoding'].eql?('gzip') && !(body.nil? || body.empty?) then - gzip = Zlib::Inflate.new(Zlib::MAX_WBITS + 16) - body = gzip.inflate(body) - gzip.close - end - fail APIError.new(:code => response.code, - :response_headers => response.headers, - :response_body => body), - response.message + data = nil end + return data, response.code, response.headers end + end + + # Check if an http request should be retried + def should_retry(attempt, retry_config, http_code) + (http_code == 429 || http_code >= 500) && retry_config["maxRetries"] > attempt && retry_config["enableRetry"] + end - if opts[:return_type] - data = deserialize(opts[:api_version], response, opts[:return_type]) + # Calculate the sleep interval between 2 retry attempts + def calculate_retry_interval(response, retry_config, attempt, timeout) + backoff_base = retry_config["backoffBase"] + backoff_multiplier = retry_config["backoffMultiplier"] + reset_header = response.headers['X-Ratelimit-Reset'] + if !reset_header.nil? && !reset_header.empty? + sleep_time = reset_header.to_i else - data = nil + sleep_time = (backoff_multiplier**attempt) * backoff_base + if timeout && timeout > 0 + sleep_time = [timeout, sleep_time].min + end end - return data, response.code, response.headers + sleep_time end # Build the HTTP request diff --git a/.generator/src/generator/templates/configuration.j2 b/.generator/src/generator/templates/configuration.j2 index 8ba6d2ab4607..d0f755c2c626 100644 --- a/.generator/src/generator/templates/configuration.j2 +++ b/.generator/src/generator/templates/configuration.j2 @@ -138,6 +138,9 @@ module {{ module_name }} # Password for proxy server authentication attr_accessor :http_proxypass + # Configuration for retry behavior + attr_accessor :retry_config + def initialize {%- set default_server = openapi.servers[0]|format_server %} @scheme = '{{ default_server.scheme }}' @@ -149,6 +152,7 @@ module {{ module_name }} @server_operation_variables = {} @api_key = {} @api_key_prefix = {} + @retry_config = {} @timeout = nil @client_side_validation = true @verify_ssl = true @@ -179,6 +183,10 @@ module {{ module_name }} {%- for name, schema in openapi.components.securitySchemes.items() if "x-env-name" in schema and schema.in == "header" and schema.type == "apiKey" %} @api_key['{{ name }}'] = ENV['{{ schema["x-env-name"] }}'] if ENV.key? '{{ schema["x-env-name"] }}' {%- endfor %} + @retry_config['enableRetry'] = false + @retry_config['backoffBase'] = 2 + @retry_config['backoffMultiplier'] = 2 + @retry_config['maxRetries'] = 3 yield(self) if block_given? end From 6951443906baaf2f1cc23bfcee373f07c0268b88 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Mon, 21 Aug 2023 13:05:57 +0000 Subject: [PATCH 09/19] pre-commit fixes --- README.md | 8 ++++++-- lib/datadog_api_client/api_client.rb | 4 ++-- lib/datadog_api_client/configuration.rb | 9 +++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f1ce2d7fd960..34676fdfd255 100644 --- a/README.md +++ b/README.md @@ -174,12 +174,16 @@ config = DatadogAPIClient::Configuration.new config.retry_config['enableRetry'] = true client = DatadogAPIClient::APIClient.new(config) ``` -The interval between 2 retry attempts will be the value of the `x-ratelimit-reset` response header when available. + +The interval between 2 retry attempts will be the value of the `x-ratelimit-reset` response header when available. If not, it will be : + ```ruby (retry_config['backoffMultiplier'] ** current_retry_count) * retry_config['backoffBase'] ``` -The maximum number of retry attempts is `3` by default and can be modified with + +The maximum number of retry attempts is `3` by default and can be modified with + ```ruby retry_config['maxRetries'] ``` diff --git a/lib/datadog_api_client/api_client.rb b/lib/datadog_api_client/api_client.rb index c3bdf5a46dad..f9b2e0f6dc30 100644 --- a/lib/datadog_api_client/api_client.rb +++ b/lib/datadog_api_client/api_client.rb @@ -473,7 +473,7 @@ def build_collection_param(param, collection_format) # @param [Object] default The default value, if not found # @return [Object] The value found, or default # @!visibility private - def get_attribute_from_path(obj, attribute_path, default = nil) + def get_attribute_from_path(obj, attribute_path, default=nil) for attr in attribute_path.split(".") do case obj when Hash @@ -561,4 +561,4 @@ def message msg end end -end +end \ No newline at end of file diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index 4babb7ae1090..1fb31046e0fc 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -424,7 +424,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -476,7 +476,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -528,7 +528,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -580,4 +580,5 @@ def to_hash self.data end end -end + +end \ No newline at end of file From 1e9b82af806461d38e582c976e77cf905157c2fb Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Mon, 21 Aug 2023 18:38:15 +0200 Subject: [PATCH 10/19] change how configs are made --- .../src/generator/templates/api_client.j2 | 12 ++++---- .../src/generator/templates/configuration.j2 | 22 +++++++++----- lib/datadog_api_client/api_client.rb | 16 +++++----- lib/datadog_api_client/configuration.rb | 29 +++++++++++-------- spec/retry_spec.rb | 2 +- 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/.generator/src/generator/templates/api_client.j2 b/.generator/src/generator/templates/api_client.j2 index 20a45516da3d..80e7b5712dcf 100644 --- a/.generator/src/generator/templates/api_client.j2 +++ b/.generator/src/generator/templates/api_client.j2 @@ -98,8 +98,8 @@ module {{ module_name }} body = gzip.inflate(body) gzip.close end - if should_retry(attempt, @config.retry_config, response.code) - sleep calculate_retry_interval(response, @config.retry_config, attempt, @config.timeout) + if should_retry(attempt, @config.max_retries, response.code, @config.enable_retry) + sleep calculate_retry_interval(response, @config.backoff_base, @config.backoff_multiplier, attempt, @config.timeout) attempt = attempt + 1 next else @@ -121,14 +121,12 @@ module {{ module_name }} end # Check if an http request should be retried - def should_retry(attempt, retry_config, http_code) - (http_code == 429 || http_code >= 500) && retry_config["maxRetries"] > attempt && retry_config["enableRetry"] + def should_retry(attempt, max_retries, http_code, enable_retry) + (http_code == 429 || http_code >= 500) && max_retries > attempt && enable_retry end # Calculate the sleep interval between 2 retry attempts - def calculate_retry_interval(response, retry_config, attempt, timeout) - backoff_base = retry_config["backoffBase"] - backoff_multiplier = retry_config["backoffMultiplier"] + def calculate_retry_interval(response, backoff_base, backoff_multiplier, attempt, timeout) reset_header = response.headers['X-Ratelimit-Reset'] if !reset_header.nil? && !reset_header.empty? sleep_time = reset_header.to_i diff --git a/.generator/src/generator/templates/configuration.j2 b/.generator/src/generator/templates/configuration.j2 index d0f755c2c626..73c1ad7ddda0 100644 --- a/.generator/src/generator/templates/configuration.j2 +++ b/.generator/src/generator/templates/configuration.j2 @@ -138,8 +138,15 @@ module {{ module_name }} # Password for proxy server authentication attr_accessor :http_proxypass - # Configuration for retry behavior - attr_accessor :retry_config + # Enable retry when rate limited + attr_accessor :enable_retry + + # Retrt backoff calculation parameters + attr_accessor :backoff_base + attr_accessor :backoff_multiplier + + # Maximum number of retry attempts allowed + attr_accessor :max_retries def initialize {%- set default_server = openapi.servers[0]|format_server %} @@ -152,7 +159,10 @@ module {{ module_name }} @server_operation_variables = {} @api_key = {} @api_key_prefix = {} - @retry_config = {} + @enable_retry = false + @backoff_base = 2 + @backoff_multiplier = 2 + @max_retries = 3 @timeout = nil @client_side_validation = true @verify_ssl = true @@ -183,11 +193,7 @@ module {{ module_name }} {%- for name, schema in openapi.components.securitySchemes.items() if "x-env-name" in schema and schema.in == "header" and schema.type == "apiKey" %} @api_key['{{ name }}'] = ENV['{{ schema["x-env-name"] }}'] if ENV.key? '{{ schema["x-env-name"] }}' {%- endfor %} - @retry_config['enableRetry'] = false - @retry_config['backoffBase'] = 2 - @retry_config['backoffMultiplier'] = 2 - @retry_config['maxRetries'] = 3 - + yield(self) if block_given? end diff --git a/lib/datadog_api_client/api_client.rb b/lib/datadog_api_client/api_client.rb index f9b2e0f6dc30..8df51fb708a7 100644 --- a/lib/datadog_api_client/api_client.rb +++ b/lib/datadog_api_client/api_client.rb @@ -109,8 +109,8 @@ def call_api(http_method, path, opts = {}) body = gzip.inflate(body) gzip.close end - if should_retry(attempt, @config.retry_config, response.code) - sleep calculate_retry_interval(response, @config.retry_config, attempt, @config.timeout) + if should_retry(attempt, @config.max_retries, response.code, @config.enable_retry) + sleep calculate_retry_interval(response, @config.backoff_base, @config.backoff_multiplier, attempt, @config.timeout) attempt = attempt + 1 next else @@ -132,14 +132,12 @@ def call_api(http_method, path, opts = {}) end # Check if an http request should be retried - def should_retry(attempt, retry_config, http_code) - (http_code == 429 || http_code >= 500) && retry_config["maxRetries"] > attempt && retry_config["enableRetry"] + def should_retry(attempt, max_retries, http_code, enable_retry) + (http_code == 429 || http_code >= 500) && max_retries > attempt && enable_retry end # Calculate the sleep interval between 2 retry attempts - def calculate_retry_interval(response, retry_config, attempt, timeout) - backoff_base = retry_config["backoffBase"] - backoff_multiplier = retry_config["backoffMultiplier"] + def calculate_retry_interval(response, backoff_base, backoff_multiplier, attempt, timeout) reset_header = response.headers['X-Ratelimit-Reset'] if !reset_header.nil? && !reset_header.empty? sleep_time = reset_header.to_i @@ -473,7 +471,7 @@ def build_collection_param(param, collection_format) # @param [Object] default The default value, if not found # @return [Object] The value found, or default # @!visibility private - def get_attribute_from_path(obj, attribute_path, default=nil) + def get_attribute_from_path(obj, attribute_path, default = nil) for attr in attribute_path.split(".") do case obj when Hash @@ -561,4 +559,4 @@ def message msg end end -end \ No newline at end of file +end diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index 1fb31046e0fc..98da5e0169b2 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -149,8 +149,15 @@ class Configuration # Password for proxy server authentication attr_accessor :http_proxypass - # Configuration for retry behavior - attr_accessor :retry_config + # Enable retry when rate limited + attr_accessor :enable_retry + + # Retrt backoff calculation parameters + attr_accessor :backoff_base + attr_accessor :backoff_multiplier + + # Maximum number of retry attempts allowed + attr_accessor :max_retries def initialize @scheme = 'https' @@ -162,7 +169,10 @@ def initialize @server_operation_variables = {} @api_key = {} @api_key_prefix = {} - @retry_config = {} + @enable_retry = false + @backoff_base = 2 + @backoff_multiplier = 2 + @max_retries = 3 @timeout = nil @client_side_validation = true @verify_ssl = true @@ -225,10 +235,6 @@ def initialize @server_variables[:site] = ENV['DD_SITE'] if ENV.key? 'DD_SITE' @api_key['apiKeyAuth'] = ENV['DD_API_KEY'] if ENV.key? 'DD_API_KEY' @api_key['appKeyAuth'] = ENV['DD_APP_KEY'] if ENV.key? 'DD_APP_KEY' - @retry_config['enableRetry'] = false - @retry_config['backoffBase'] = 2 - @retry_config['backoffMultiplier'] = 2 - @retry_config['maxRetries'] = 3 yield(self) if block_given? end @@ -424,7 +430,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -476,7 +482,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -528,7 +534,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -580,5 +586,4 @@ def to_hash self.data end end - -end \ No newline at end of file +end diff --git a/spec/retry_spec.rb b/spec/retry_spec.rb index fe44c35fb2a6..5be80dfcf539 100644 --- a/spec/retry_spec.rb +++ b/spec/retry_spec.rb @@ -2,7 +2,7 @@ describe 'logs_archive retry test' do before do - DatadogAPIClient.configure { |c| c.retry_config["enableRetry"] = true } + DatadogAPIClient.configure { |c| c.enable_retry = true } @api_instance = DatadogAPIClient::V2::LogsArchivesAPI.new @base_path = @api_instance.api_client.build_request_url('') @body = DatadogAPIClient::V2::LogsArchiveCreateRequest.new From ff756df511313373e0284b9f20178e94b5d2ba38 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Mon, 21 Aug 2023 19:23:52 +0000 Subject: [PATCH 11/19] pre-commit fixes --- lib/datadog_api_client/api_client.rb | 4 ++-- lib/datadog_api_client/configuration.rb | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/datadog_api_client/api_client.rb b/lib/datadog_api_client/api_client.rb index 8df51fb708a7..f44f4bbfd585 100644 --- a/lib/datadog_api_client/api_client.rb +++ b/lib/datadog_api_client/api_client.rb @@ -471,7 +471,7 @@ def build_collection_param(param, collection_format) # @param [Object] default The default value, if not found # @return [Object] The value found, or default # @!visibility private - def get_attribute_from_path(obj, attribute_path, default = nil) + def get_attribute_from_path(obj, attribute_path, default=nil) for attr in attribute_path.split(".") do case obj when Hash @@ -559,4 +559,4 @@ def message msg end end -end +end \ No newline at end of file diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index 98da5e0169b2..5de9c7a6e98b 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -235,7 +235,7 @@ def initialize @server_variables[:site] = ENV['DD_SITE'] if ENV.key? 'DD_SITE' @api_key['apiKeyAuth'] = ENV['DD_API_KEY'] if ENV.key? 'DD_API_KEY' @api_key['appKeyAuth'] = ENV['DD_APP_KEY'] if ENV.key? 'DD_APP_KEY' - + yield(self) if block_given? end @@ -430,7 +430,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -482,7 +482,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -534,7 +534,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -586,4 +586,5 @@ def to_hash self.data end end -end + +end \ No newline at end of file From de0424d5738438ffbc82463960f008145076c126 Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Wed, 23 Aug 2023 13:48:59 +0200 Subject: [PATCH 12/19] update readme doc --- .generator/src/generator/templates/configuration.j2 | 4 ++-- README.md | 7 ++++--- lib/datadog_api_client/configuration.rb | 13 ++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.generator/src/generator/templates/configuration.j2 b/.generator/src/generator/templates/configuration.j2 index 73c1ad7ddda0..548844778651 100644 --- a/.generator/src/generator/templates/configuration.j2 +++ b/.generator/src/generator/templates/configuration.j2 @@ -141,7 +141,7 @@ module {{ module_name }} # Enable retry when rate limited attr_accessor :enable_retry - # Retrt backoff calculation parameters + # Retry backoff calculation parameters attr_accessor :backoff_base attr_accessor :backoff_multiplier @@ -193,7 +193,7 @@ module {{ module_name }} {%- for name, schema in openapi.components.securitySchemes.items() if "x-env-name" in schema and schema.in == "header" and schema.type == "apiKey" %} @api_key['{{ name }}'] = ENV['{{ schema["x-env-name"] }}'] if ENV.key? '{{ schema["x-env-name"] }}' {%- endfor %} - + yield(self) if block_given? end diff --git a/README.md b/README.md index 34676fdfd255..63f932c93aa6 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ To enable the client to retry when rate limited (status 429) or status 500 and a ```ruby config = DatadogAPIClient::Configuration.new -config.retry_config['enableRetry'] = true +config.enable_retry = true client = DatadogAPIClient::APIClient.new(config) ``` @@ -179,13 +179,14 @@ The interval between 2 retry attempts will be the value of the `x-ratelimit-rese If not, it will be : ```ruby -(retry_config['backoffMultiplier'] ** current_retry_count) * retry_config['backoffBase'] +(config.backoffMultiplier ** current_retry_count) * config.backoffBase + ``` The maximum number of retry attempts is `3` by default and can be modified with ```ruby -retry_config['maxRetries'] +config.maxRetries ``` ## Documentation diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index 5de9c7a6e98b..6f687c3bfb71 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -152,7 +152,7 @@ class Configuration # Enable retry when rate limited attr_accessor :enable_retry - # Retrt backoff calculation parameters + # Retry backoff calculation parameters attr_accessor :backoff_base attr_accessor :backoff_multiplier @@ -235,7 +235,7 @@ def initialize @server_variables[:site] = ENV['DD_SITE'] if ENV.key? 'DD_SITE' @api_key['apiKeyAuth'] = ENV['DD_API_KEY'] if ENV.key? 'DD_API_KEY' @api_key['appKeyAuth'] = ENV['DD_APP_KEY'] if ENV.key? 'DD_APP_KEY' - + yield(self) if block_given? end @@ -430,7 +430,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -482,7 +482,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -534,7 +534,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -586,5 +586,4 @@ def to_hash self.data end end - -end \ No newline at end of file +end From 1cc32cac2196a6e27af3b357dad6479aeb27f897 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Wed, 23 Aug 2023 11:51:22 +0000 Subject: [PATCH 13/19] pre-commit fixes --- lib/datadog_api_client/configuration.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index 6f687c3bfb71..c089d2908cb7 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -430,7 +430,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -482,7 +482,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -534,7 +534,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -586,4 +586,5 @@ def to_hash self.data end end -end + +end \ No newline at end of file From 2b9e3bf31a37d6cb2b7890ee0c1e7a3315eafd0e Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Wed, 23 Aug 2023 14:09:58 +0200 Subject: [PATCH 14/19] adds validation for backoff_base --- README.md | 1 - lib/datadog_api_client/configuration.rb | 7 +++++++ spec/configuration_spec.rb | 17 +++++++++++++++++ spec/retry_spec.rb | 5 ++++- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 63f932c93aa6..ffade8e7d3e6 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,6 @@ If not, it will be : ```ruby (config.backoffMultiplier ** current_retry_count) * config.backoffBase - ``` The maximum number of retry attempts is `3` by default and can be modified with diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index 6f687c3bfb71..553a5684cd72 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -248,6 +248,13 @@ def configure yield(self) if block_given? end + def backoff_base=(value) + if value < 2 + raise ArgumentError, 'backoff_base cannot be smaller than 2' + end + @backoff_base = value + end + def scheme=(scheme) # remove :// from scheme @scheme = scheme.sub(/:\/\//, '') diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb index d47d11b647eb..60a4d9df7f46 100644 --- a/spec/configuration_spec.rb +++ b/spec/configuration_spec.rb @@ -42,4 +42,21 @@ end end end + + describe '#backoff_base' do + context 'when setting a valid backoff_base value > 2' do + it 'sets the backoff_base attribute' do + config.backoff_base = 3 + expect(config.backoff_base).to eq(3) + end + end + end + + context 'when setting an invalid backoff_base value < 2' do + it 'raises an ArgumentError' do + expect { config.backoff_base = 1 }.to raise_error(ArgumentError, 'backoff_base cannot be smaller than 2') + end + end + + end diff --git a/spec/retry_spec.rb b/spec/retry_spec.rb index 5be80dfcf539..2730008c7363 100644 --- a/spec/retry_spec.rb +++ b/spec/retry_spec.rb @@ -2,7 +2,10 @@ describe 'logs_archive retry test' do before do - DatadogAPIClient.configure { |c| c.enable_retry = true } + DatadogAPIClient.configure do |c| + c.enable_retry = true + c.backoff_base = 2 + end @api_instance = DatadogAPIClient::V2::LogsArchivesAPI.new @base_path = @api_instance.api_client.build_request_url('') @body = DatadogAPIClient::V2::LogsArchiveCreateRequest.new From 6c074162aa35c6a73cdba595e67029afbcdae4b2 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Wed, 23 Aug 2023 12:14:21 +0000 Subject: [PATCH 15/19] pre-commit fixes --- lib/datadog_api_client/configuration.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index f0fe28f8c70b..c089d2908cb7 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -248,13 +248,6 @@ def configure yield(self) if block_given? end - def backoff_base=(value) - if value < 2 - raise ArgumentError, 'backoff_base cannot be smaller than 2' - end - @backoff_base = value - end - def scheme=(scheme) # remove :// from scheme @scheme = scheme.sub(/:\/\//, '') From 8482379f3bf82ab5bb94c81422c2a64d937dc337 Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Wed, 23 Aug 2023 14:26:12 +0200 Subject: [PATCH 16/19] change generator --- .generator/src/generator/templates/configuration.j2 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.generator/src/generator/templates/configuration.j2 b/.generator/src/generator/templates/configuration.j2 index 548844778651..9fc9363b6ec4 100644 --- a/.generator/src/generator/templates/configuration.j2 +++ b/.generator/src/generator/templates/configuration.j2 @@ -202,6 +202,13 @@ module {{ module_name }} @@default ||= Configuration.new end + def backoff_base=(value) + if value < 2 + raise ArgumentError, 'backoff_base cannot be smaller than 2' + end + @backoff_base = value + end + def configure yield(self) if block_given? end From 3fb2fa6b46a343a691533d962404cf83e0ec4c6a Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Wed, 23 Aug 2023 12:29:40 +0000 Subject: [PATCH 17/19] pre-commit fixes --- lib/datadog_api_client/configuration.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index c089d2908cb7..b72b25054d62 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -244,6 +244,13 @@ def self.default @@default ||= Configuration.new end + def backoff_base=(value) + if value < 2 + raise ArgumentError, 'backoff_base cannot be smaller than 2' + end + @backoff_base = value + end + def configure yield(self) if block_given? end From b80809354991599d8612b03e79135be8a62587cd Mon Sep 17 00:00:00 2001 From: HantingZhang2 Date: Wed, 23 Aug 2023 14:34:09 +0200 Subject: [PATCH 18/19] add validation back --- lib/datadog_api_client/configuration.rb | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index c089d2908cb7..d412d7fca1e3 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -244,6 +244,13 @@ def self.default @@default ||= Configuration.new end + def backoff_base=(value) + if value < 2 + raise ArgumentError, 'backoff_base cannot be smaller than 2' + end + @backoff_base = value + end + def configure yield(self) if block_given? end @@ -430,7 +437,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -482,7 +489,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -534,7 +541,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -586,5 +593,4 @@ def to_hash self.data end end - -end \ No newline at end of file +end From 1f4cb697eefc7ea80e9c0791f94171c6db0980c2 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Wed, 23 Aug 2023 12:36:37 +0000 Subject: [PATCH 19/19] pre-commit fixes --- lib/datadog_api_client/configuration.rb | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/datadog_api_client/configuration.rb b/lib/datadog_api_client/configuration.rb index d412d7fca1e3..b72b25054d62 100644 --- a/lib/datadog_api_client/configuration.rb +++ b/lib/datadog_api_client/configuration.rb @@ -437,7 +437,7 @@ def operation_server_settings default_value: "ip-ranges", } } - } + } ], "v1.submit_log": [ { @@ -489,7 +489,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], "v2.submit_log": [ { @@ -541,7 +541,7 @@ def operation_server_settings default_value: "http-intake.logs", } } - } + } ], } end @@ -593,4 +593,5 @@ def to_hash self.data end end -end + +end \ No newline at end of file