Skip to content

Commit

Permalink
Added a large suite of unit tests partition interfaces.
Browse files Browse the repository at this point in the history
Fixed a number of issues revealed in testing.
  • Loading branch information
trevorrowe committed Apr 25, 2016
1 parent 3d62c6c commit 9ec5145
Show file tree
Hide file tree
Showing 6 changed files with 569 additions and 117 deletions.
38 changes: 11 additions & 27 deletions aws-sdk-core/lib/aws-sdk-core/partitions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ class << self

# @param [Hash] new_partitions
# @api private
def add_partitions(new_partitions)
def add(new_partitions)
new_partitions['partitions'].each do |partition|
default_list.add_partition(Partition.build(partition))
defaults['partitions'] << partition
end
end

# @api private
def clear_partitions
def clear
default_list.clear
defaults['partitions'].clear
end
Expand All @@ -38,32 +38,16 @@ def default_list
@default_list ||= PartitionList.build(defaults)
end

# @param [String] svc_id
# @return [String] The service module name.
# @api priviate
def service_name(svc_id)
if service_names.key?(svc_id)
service_names[svc_id]
else
msg = "invalid service id #{svc_id.inspect}; valid service ids "
msg << "include %s" % [service_names.keys.join(', ')]
raise ArgumentError, msg
end
end

# @return [Hash<String,String>] Returns a hash of service id keys
# and service module name values.
# @return [Hash<String,String>] Returns a map of service module names
# to their id as used in the endpoints.json document.
# @api private
def service_names
@service_names ||= begin
service_models = "#{File.dirname(__FILE__)}/../../service-models.json"
service_models = Aws::Json.load_file(service_models)
service_models.inject({}) do |names, (name, artifact)|
svc_id = artifact.split('/').first
# TODO : Remove this once endpoints.json has been corrected
svc_id = 'data.iot' if svc_id == 'iot-data'
names[svc_id] = name
names
def service_ids
@service_ids ||= begin
services = "#{File.dirname(__FILE__)}/../../service-models.json"
services = Aws::Json.load_file(services)
services.inject({}) do |ids, (name, svc)|
ids[name] = svc['endpoint'] #if svc['endpoint']
ids
end
end
end
Expand Down
10 changes: 6 additions & 4 deletions aws-sdk-core/lib/aws-sdk-core/partitions/partition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@ def build_regions(partition)
# @param [Hash] partition
# @return [Hash<String,Service>]
def build_services(partition)
partition['services'].inject({}) do |services, (svc_id, svc_data)|
if Partitions.service_names.key?(svc_id)
service = Service.build(svc_id, svc_data, partition)
services[service.name] = service
Partitions.service_ids.inject({}) do |services, (svc_name, svc_id)|
if partition['services'].key?(svc_id)
svc_data = partition['services'][svc_id]
services[svc_name] = Service.build(svc_name, svc_data, partition)
else
services[svc_name] = Service.build(svc_name, {'endpoints' => {}}, partition)
end
services
end
Expand Down
33 changes: 25 additions & 8 deletions aws-sdk-core/lib/aws-sdk-core/partitions/region.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ class Region
# @option options [required, String] :name
# @option options [required, String] :description
# @option options [required, String] :partition_name
# @option options [required, Set<String>] :service_names
# @option options [required, Set<String>] :services
# @api private
def initialize(options = {})
@name = options[:name]
@description = options[:description]
@partition = options[:partition]
@partition_name = options[:partition_name]
@service_names = options[:service_names]
@services = options[:services]
end

# @return [String] The name of this region, e.g. "us-east-1".
Expand All @@ -30,7 +29,7 @@ def initialize(options = {})
# @return [Set<String>] The list of services available in this region.
# Service names are the module names as used by the AWS SDK
# for Ruby.
attr_reader :service_names
attr_reader :services

class << self

Expand All @@ -40,21 +39,39 @@ def build(region_name, region, partition)
name: region_name,
description: region['description'],
partition_name: partition['partition'],
service_names: region_services(region_name, partition)
services: region_services(region_name, partition)
)
end

private

def region_services(region_name, partition)
partition['services'].inject(Set.new) do |services, (svc_id, svc)|
if svc['endpoints'].key?(region_name) && Partitions.service_names.key?(svc_id)
services << Partitions.service_name(svc_id)
Partitions.service_ids.inject(Set.new) do |services, (svc_name, svc_id)|
if svc = partition['services'][svc_id]
services << svc_name if service_in_region?(svc, region_name)
else
#raise "missing endpoints for #{svc_name} / #{svc_id}"
end
services
end
end

def service_in_region?(svc, region_name)
svc_endpoints_contains_region?(svc, region_name) ||
svc_partition_endpoint_matches_region?(svc, region_name)
end

def svc_endpoints_contains_region?(svc, region_name)
svc['endpoints'].key?(region_name)
end

def svc_partition_endpoint_matches_region?(svc, region_name)
if pe = svc['partitionEndpoint']
region = svc['endpoints'][pe].fetch('credentialScope', {})['region']
region == region_name
end
end

end
end
end
Expand Down
36 changes: 26 additions & 10 deletions aws-sdk-core/lib/aws-sdk-core/partitions/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ class Service
# @option options [required, String] :partition_name
# @option options [required, Set<String>] :region_name
# @option options [required, Boolean] :regionalized
# @option options [String] :partition_endpoint
# @option options [String] :partition_region
# @api private
def initialize(options = {})
@name = options[:name]
@partition_name = options[:partition_name]
@region_names = options[:region_names]
@regions = options[:regions]
@regionalized = options[:regionalized]
@partition_endpoint = options[:partition_endpoint]
@partition_region = options[:partition_region]
@regions << @partition_region if !@regionalized
end

# @return [String] The name of this service. The name is the module
Expand All @@ -27,11 +28,11 @@ def initialize(options = {})

# @return [Set<String>] The regions this service is available in.
# Regions are scoped to the partition.
attr_reader :region_names
attr_reader :regions

# @return [String,nil] The global patition endpoint for this service.
# May be `nil`.
attr_reader :partition_endpoint
attr_reader :partition_region

# Returns `false` if the service operates with a single global
# endpoint for the current partition, returns `true` if the service
Expand All @@ -47,23 +48,38 @@ def regionalized?
class << self

# @api private
def build(svc_id, service, partition)
def build(service_name, service, partition)
Service.new(
name: Partitions.service_name(svc_id),
name: service_name,
partition_name: partition['partition'],
region_names: region_names(service, partition),
regions: regions(service, partition),
regionalized: service['isRegionalized'] != false,
partition_endpoint: service['partitionEndpoint']
partition_region: partition_region(service)
)
end

private

def region_names(service, partition)
def regions(service, partition)
names = Set.new(partition['regions'].keys & service['endpoints'].keys)
names - ["#{partition['partition']}-global"]
end

def partition_region(service)
if service['partitionEndpoint']
endpoint = service['endpoints'][service['partitionEndpoint']]
region = if endpoint['credentialScope']
endpoint['credentialScope']['region']
elsif service['defaults'] && service['defaults']['credentialScope']
service['defaults']['credentialScope']['region']
end
unless region
raise "missing partition endpoint region for #{service.inspect}"
end
region
end
end

end
end
end
Expand Down
Loading

0 comments on commit 9ec5145

Please sign in to comment.