@@ -6,6 +6,7 @@ local build_request = require("resty.aws.request.build")
6
6
local sign_request = require (" resty.aws.request.sign" )
7
7
local execute_request = require (" resty.aws.request.execute" )
8
8
local split = require (" pl.utils" ).split
9
+ local tablex = require (" pl.tablex" )
9
10
10
11
11
12
@@ -70,44 +71,54 @@ AWS.__index = lookup_helper
70
71
71
72
72
73
73
- local aws_config do
74
- aws_config = {
75
- region = require (" resty.aws.raw-api.region_config_data" ),
76
- api = {},
77
- }
74
+ local aws_config = {
75
+ region = require (" resty.aws.raw-api.region_config_data" ),
76
+ api = {},
77
+ }
78
78
79
+ local load_api
80
+ do
79
81
-- The API table is a map, where the index is the service-name. The value is a table.
80
82
-- The table is another map, indexed by version (string). The value of that one
81
83
-- is the raw AWS api.
82
84
-- That raw-api is loaded upon demand by meta-table magic so we only load what we need.
83
85
local list = require (" resty.aws.raw-api.table_of_contents" )
84
- for i , filename in ipairs (list ) do
86
+ local apis = {}
87
+ for _ , filename in ipairs (list ) do
85
88
-- example filename: "AWSMigrationHub-2017-05-31"
86
89
local module_name = " resty.aws.raw-api." .. filename
87
90
-- example module_name: "resty.aws.raw-api.AWSMigrationHub-2017-05-31"
88
- local service_name , version = assert (filename :match (" ^(.-)%-(%d%d%d%d%-%d%d%-%d%d)$" ))
89
- -- example service_name: "AWSMigrationHub"
91
+ -- example table_of_contents: "MigrationHub:AWSMigrationHub-2017-05-31"
92
+ local service_id , _ , version = assert (filename :match (" ^(.-)%:(.-)%-(%d%d%d%d%-%d%d%-%d%d)$" ))
93
+ -- example service_id: "MigrationHub"
90
94
-- example version: "2017-05-31"
91
- local service_table = aws_config .api [service_name ]
92
- if not service_table then
93
- service_table = {}
94
- aws_config .api [service_name ] = service_table
95
- end
96
- -- load the file and dereference shapes
97
- local api = require (module_name )
98
- dereference_service (api )
95
+ local service_table = apis [service_id ] or {}
96
+ service_table [version ] = module_name
99
97
100
- service_table [version ] = api
98
+ local sorted_versions = table.sort (tablex .keys (service_table ))
99
+ service_table .latest = service_table [sorted_versions [# service_table ]]
101
100
102
- if service_table .latest then
103
- -- update 'latest' if this one is newer
104
- if service_table .latest .metadata .apiVersion < version then
105
- service_table .latest = api
106
- end
107
- else
108
- -- we're the only one, and hence also 'latest' so far
109
- service_table .latest = api
101
+ apis [service_id ] = service_table
102
+ end
103
+
104
+ local cache = setmetatable ({}, { __mode = " v" })
105
+
106
+ function load_api (service , version )
107
+ local module_name = apis [service ] and apis [service ][version ]
108
+ if not module_name then
109
+ return nil , " unknown service: " .. tostring (service ) .. " /" .. tostring (version )
110
+ end
111
+
112
+ local api = cache [module_name ]
113
+ if api then
114
+ return api
110
115
end
116
+
117
+ api = require (module_name )
118
+ dereference_service (api )
119
+
120
+ cache [module_name ] = api
121
+ return api
111
122
end
112
123
end
113
124
@@ -378,13 +389,9 @@ function AWS:new(config)
378
389
end
379
390
380
391
-- create service methods/constructors
381
- for service_name , versions in pairs (aws_config .api ) do
392
+ for service_id in pairs (aws_config .api ) do
382
393
-- Create service specific functions, by `serviceId`
383
-
384
- local serviceId = versions [next (versions )].metadata .serviceId
385
- local cleanId = serviceId :gsub (" " , " " ) -- for interface drop all spaces
386
-
387
- aws_instance [cleanId ] = function (aws , config )
394
+ aws_instance [service_id ] = function (aws , config )
388
395
if getmetatable (aws ) ~= AWS then
389
396
error (" must instantiate AWS services by calling aws_instance:ServiceName(config)" , 2 )
390
397
end
@@ -404,9 +411,9 @@ function AWS:new(config)
404
411
405
412
-- create the service
406
413
-- `config.apiVersion`: the api version to use
407
- local api = versions [ service_config .apiVersion ]
414
+ local api = load_api ( service_id , service_config .apiVersion )
408
415
if not api then
409
- return nil , (" service '%s' does not have an apiVersion '%s'" ):format (serviceId , tostring (service_config .apiVersion ))
416
+ return nil , (" service '%s' does not have an apiVersion '%s'" ):format (service_id , tostring (service_config .apiVersion ))
410
417
end
411
418
if service_config .apiVersion == " latest" then
412
419
service_config .apiVersion = api .metadata .apiVersion
0 commit comments