Skip to content

Commit

Permalink
Instance plugins (#3051)
Browse files Browse the repository at this point in the history
  • Loading branch information
mullermp committed Jun 20, 2024
1 parent e10c7ee commit ab1503e
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
describe 'Interfaces' do

before(:all) do
# TODO : support Aws.config[:sample] = { ... }
@tmpdir = SpecHelper.generate_service(['Sample'], multiple_files: true)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ module {{module_name}}
{{#client_constructor}}
# @overload initialize(options)
# @param [Hash] options
#
# @option options [Array<Seahorse::Client::Plugin>] :plugins ([]])
# A list of plugins to apply to the client. Each plugin is either a
# class name or an instance of a plugin class.
#
{{>documentation}}
{{/client_constructor}}
def initialize(*args)
Expand Down
4 changes: 2 additions & 2 deletions build_tools/services.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ class ServiceEnumerator
MANIFEST_PATH = File.expand_path('../../services.json', __FILE__)

# Minimum `aws-sdk-core` version for new gem builds
MINIMUM_CORE_VERSION = "3.197.0"
MINIMUM_CORE_VERSION = "3.198.0"

# Minimum `aws-sdk-core` version for new S3 gem builds
MINIMUM_CORE_VERSION_S3 = "3.197.0"
MINIMUM_CORE_VERSION_S3 = "3.198.0"

EVENTSTREAM_PLUGIN = "Aws::Plugins::EventStreamConfiguration"

Expand Down
2 changes: 2 additions & 0 deletions gems/aws-sdk-core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Unreleased Changes
------------------

* Feature - Support `:plugins` option on all Clients or using `Aws.config[:plugins]`.

3.197.2 (2024-06-20)
------------------

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module Plugins
# @api private
class GlobalConfiguration < Seahorse::Client::Plugin

@identifiers = Set.new()
@identifiers = Set.new

# @api private
def before_initialize(client_class, options)
Expand All @@ -55,17 +55,18 @@ def before_initialize(client_class, options)
private

def apply_service_defaults(client_class, options)
if defaults = Aws.config[client_class.identifier]
defaults.each do |option_name, default|
options[option_name] = default unless options.key?(option_name)
end
return unless (defaults = Aws.config[client_class.identifier])

defaults.each do |option_name, default|
options[option_name] = default unless options.key?(option_name)
end
end

def apply_aws_defaults(client_class, options)
def apply_aws_defaults(_client_class, options)
Aws.config.each do |option_name, default|
next if self.class.identifiers.include?(option_name)
next if options.key?(option_name)

options[option_name] = default
end
end
Expand All @@ -80,9 +81,7 @@ def add_identifier(identifier)

# @return [Set<String>]
# @api private
def identifiers
@identifiers
end
attr_reader :identifiers

end
end
Expand Down
1 change: 0 additions & 1 deletion gems/aws-sdk-core/lib/aws-sdk-core/plugins/retry_errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ class RetryErrors < Seahorse::Client::Plugin
functionality of `standard` mode along with automatic client side
throttling. This is a provisional mode that may change behavior
in the future.
DOCS
resolve_retry_mode(cfg)
end
Expand Down
24 changes: 17 additions & 7 deletions gems/aws-sdk-core/lib/seahorse/client/base.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require 'thread'

module Seahorse
module Client
class Base
Expand Down Expand Up @@ -60,6 +58,7 @@ def operation_names
def build_config(plugins, options)
config = Configuration.new
config.add_option(:api)
config.add_option(:plugins)
plugins.each do |plugin|
plugin.add_options(config) if plugin.respond_to?(:add_options)
end
Expand Down Expand Up @@ -96,9 +95,9 @@ def context_for(operation_name, params)
class << self

def new(options = {})
plugins = build_plugins
options = options.dup
before_initialize(plugins, options)
plugins = build_plugins(self.plugins + options.fetch(:plugins, []))
plugins = before_initialize(plugins, options)
client = allocate
client.send(:initialize, plugins, options)
client
Expand Down Expand Up @@ -209,17 +208,28 @@ def define_operation_methods
include(operations_module)
end

def build_plugins
def build_plugins(plugins)
plugins.map { |plugin| plugin.is_a?(Class) ? plugin.new : plugin }
end

def before_initialize(plugins, options)
plugins.each do |plugin|
plugin.before_initialize(self, options) if plugin.respond_to?(:before_initialize)
queue = Queue.new
plugins.each { |plugin| queue.push(plugin) }
until queue.empty?
plugin = queue.pop
next unless plugin.respond_to?(:before_initialize)

plugins_before = options.fetch(:plugins, [])
plugin.before_initialize(self, options)
plugins_after = build_plugins(options.fetch(:plugins, []) - plugins_before)
# Plugins with before_initialize can add other plugins
plugins_after.each { |p| queue.push(p); plugins << p }
end
plugins
end

def inherited(subclass)
super
subclass.instance_variable_set('@plugins', PluginList.new(@plugins))
end

Expand Down
1 change: 0 additions & 1 deletion gems/aws-sdk-core/lib/seahorse/client/plugins/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ class Endpoint < Plugin
'http://example.com'
'https://example.com'
'http://example.com:123'
DOCS

def add_handlers(handlers, config)
Expand Down
54 changes: 52 additions & 2 deletions gems/aws-sdk-core/spec/aws/plugins/global_configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,23 @@ module Plugins
option(:property, 'plugin-default')
end)

let(:plugin) do
p = double('plugin')
allow(p).to receive(:is_a?).with(kind_of(Class)).and_return(false)
p
end

let(:options) do
{
region: 'us-east-1',
credentials: Credentials.new('akid', 'secret'),
plugins: [plugin]
}
end

before(:each) do
Aws.config.clear
Aws.config[:region] = 'us-east-1'
Aws.config[:credentials] = Credentials.new('akid', 'secret')
Aws.config = options
end

before(:all) do
Expand Down Expand Up @@ -45,6 +58,43 @@ module Plugins
expect(GlobalConfigClient.new(property: 'arg').config.property).to eq('arg')
end

context 'plugins' do
it 'instructs plugins to #before_initialize' do
expect(plugin).to receive(:before_initialize).with(GlobalConfigClient, options)
GlobalConfigClient.new
end

it 'instructs plugins to #add_options' do
expect(plugin).to receive(:add_options)
GlobalConfigClient.new
end

it 'instructs plugins to #add_handlers' do
expect(plugin).to receive(:add_handlers).
with(kind_of(Seahorse::Client::HandlerList), kind_of(Struct))
GlobalConfigClient.new
end

it 'instructs plugins to #after_initialize' do
expect(plugin).to receive(:after_initialize).with(kind_of(Seahorse::Client::Base))
GlobalConfigClient.new
end

it 'does not call methods that plugin does not respond to' do
plugin = Object.new
allow(plugin).to receive(:respond_to?).with(:before_initialize).and_return(false)
allow(plugin).to receive(:respond_to?).with(:add_options).and_return(false)
allow(plugin).to receive(:respond_to?).with(:add_handlers).and_return(false)
allow(plugin).to receive(:respond_to?).with(:after_initialize).and_return(false)
expect(plugin).not_to receive(:before_initialize)
expect(plugin).not_to receive(:add_options)
expect(plugin).not_to receive(:add_handlers)
expect(plugin).not_to receive(:after_initialize)
Aws.config[:plugins] = [plugin]
GlobalConfigClient.new
end
end

end
end
end
Loading

0 comments on commit ab1503e

Please sign in to comment.