aws-sdk-ruby に cloud_formation なナニを発見
色々確認している中で
- json なナニを作るの面倒
- テスツ大変
な話がごろごろ転がっている模様。むむむ、と言いつつ aws-sdk-ruby なソースを見てみるに lib/aws/cloud_formation なるディレクトリがあることを確認。
lib/aws/cloud_formation/client.rb を見てみたところ、validate_template なるメソドに関するコメント記述を確認。
# Calls the ValidateTemplate API operation.
てことなのでこれを試験に使えないかな、という事で検討着手。
と言いつつ
client.rb が非常にメタな記述になっているのでこっち方面も掘削。定義は以下な形になってます。
define_client_methods('2010-05-15')
こちら、lib/aws/api_config/CloudFormation-2010-05-15.yml を指しているものと思われます。つうかこのメソドはどこにあるんだ、ということで確認。とりあえず、AWS::CloudFormation::Client は Core::QueryClient を継承している模様。
# Client class for AWS CloudFormation. class Client < Core::QueryClient
Core::QueryClient に定義はありませんでしたが、Core::Client を継承している事が判明。
module AWS module Core class QueryClient < Core::Client
AWS::Core::Client に定義されていることを確認。
# Defines one method for each service operation described in # the API configuration. # @param [String] api_version def define_client_methods api_version const_set(:API_VERSION, api_version) api_config = load_api_config(api_version) api_config[:operations].each do |operation| builder = request_builder_for(api_config, operation) parser = response_parser_for(api_config, operation) define_client_method(operation[:method], builder, parser) end end
む、load_api_config メソドは直上で定義されてます。
def load_api_config api_version lib = File.dirname(File.dirname(__FILE__)) path = "#{lib}/api_config/#{service_name}-#{api_version}.yml" YAML.load(File.read(path)) end
なんとなく当たってますね。つうかこないだの年末に aws-sdk な spec 読んでますね。
それは良いとして以下の記述なソレなんですが
builder = request_builder_for(api_config, operation) parser = response_parser_for(api_config, operation)
superclass な記述を確認しておこう、ということで AWS::Core::Client の reqest_builder_for やら response_parse_for の定義が以下。
# Define this in sub-classes (e.g. QueryClient, RESTClient, etc) def request_builder_for api_config, operation raise NotImplementedError end # Define this in sub-classes (e.g. QueryClient, RESTClient, etc) def response_parser_for api_config, operation raise NotImplementedError end
コメントの通り、subclass で定義せよ、ということか。そして AWS::Core::QueryClient における request_builder_for とか response_parse_for の定義が以下。
def self.request_builder_for api_config, operation QueryRequestBuilder.new(api_config[:api_version], operation) end def self.response_parser_for api_config, operation QueryResponseParser.new(operation[:outputs]) end
例えば RESTClient とかだとまた違うオブジェクトを生成して云々、な風になってるのだろうな。
嗚呼抽象化
AWS::Core::Client#define_client_method から add_client_request_method を呼び出してるんですが、してる事は
- operation という配列 (?) に引数の method_name を追加
- ClientRequestMethodBuilder.new
- method_name な手続き定義な文字列の method_def を作って module_eval 呼び出し
- 基本的には options を作って client_request 手続き呼び出し
というあたりな模様。つうか抽象度が高すぎてイメージできてなかったりしてます。つうかナチュラル爆発させてそうな気がしてるんですが validates って意味てきにアレですね。うーん困った。