]> git.donarmstrong.com Git - dsa-puppet.git/blob - 3rdparty/modules/aviator/lib/puppet/feature/aviator/core/service.rb
add aimonb/aviator to 3rdparty
[dsa-puppet.git] / 3rdparty / modules / aviator / lib / puppet / feature / aviator / core / service.rb
1 module Aviator
2
3   #
4   # Manages a service
5   #
6   class Service
7
8     class AccessDetailsNotDefinedError < StandardError
9       def initialize
10         super ":access_details is not defined."
11       end
12     end
13
14     class ProviderNotDefinedError < StandardError
15       def initialize
16         super ":provider is not defined."
17       end
18     end
19
20     class ServiceNameNotDefinedError < StandardError
21       def initialize
22         super ":service is not defined."
23       end
24     end
25
26     class SessionDataNotProvidedError < StandardError
27       def initialize(service_name, request_name)
28         super "\n\nERROR: default_session_data is not initialized and no session data was provided in\n"\
29               "the method call. You have two ways to fix this:\n\n"\
30               "   1) Call Session#authenticate before calling Session##{service_name}_service, or\n\n"\
31               "   2) If you're really sure you don't want to authenticate beforehand,\n"\
32               "      construct the method call this way:\n\n"\
33               "          service = session.#{service_name}_service\n"\
34               "          service.request :#{request_name}, :api_version => :v2, :session_data => sessiondatavar\n\n"\
35               "      Replace :v2 with whatever available version you want to use and make sure sessiondatavar\n"\
36               "      is a hash that contains, at least, the :base_url key. Other keys, such as :service_token may\n"\
37               "      be needed depending on what the request class you are calling requires.\n\n"
38       end
39     end
40
41     class UnknownRequestError < StandardError
42       def initialize(request_name, options)
43         super "Unknown request #{ request_name } #{ options }."
44       end
45     end
46
47
48     class MissingServiceEndpointError < StandardError
49       def initialize(service_name, request_name)
50         request_name = request_name.to_s.split('::').last.underscore
51         super "The session's service catalog does not have an entry for the #{ service_name } "\
52               "service. Therefore, I don't know to which base URL the request should be sent. "\
53               "This may be because you are using a default or unscoped token. If this is not your "\
54               "intention, please authenticate with a scoped token. If using a default token is your "\
55               "intention, make sure to provide a base url when you call the request. For :example => \n\n"\
56               "session.#{ service_name }_service.request :#{ request_name }, :base_url => 'http://myenv.com:9999/v2.0' do |params|\n"\
57               "  params[:example1] = 'example1'\n"\
58               "  params[:example2] = 'example2'\n"\
59               "end\n\n"
60       end
61     end
62
63     attr_accessor :default_session_data
64
65     attr_reader :service,
66                 :provider
67
68
69     def initialize(opts={})
70       @provider = opts[:provider] || (raise ProviderNotDefinedError.new)
71       @service  = opts[:service]  || (raise ServiceNameNotDefinedError.new)
72       @log_file = opts[:log_file]
73       @default_options = opts[:default_options] || {}
74
75       @default_session_data = opts[:default_session_data]
76
77       load_requests
78     end
79
80     #
81     # No longer recommended for public use. Use Aviator::Session#request instead
82     #
83     def request(request_name, options={}, &params)
84       if options[:api_version].nil? && @default_options[:api_version]
85         options[:api_version] = @default_options[:api_version]
86       end
87
88       session_data = options[:session_data] || default_session_data
89
90       raise SessionDataNotProvidedError.new(@service, request_name) unless session_data
91
92       [:base_url].each do |k|
93         session_data[k] = options[k] if options[k]
94       end
95
96       request_class = provider_module.find_request(service, request_name, session_data, options)
97
98       raise UnknownRequestError.new(request_name, options) unless request_class
99
100       # Always use :params over &params if provided
101       if options[:params]
102         params = lambda do |params|
103           options[:params].each do |key, value|
104             begin
105               params[key] = value
106             rescue NameError => e
107               raise NameError.new("Unknown param name '#{key}'")
108             end
109           end
110         end
111       end
112
113       request  = request_class.new(session_data, &params)
114
115       response = http_connection.send(request.http_method) do |r|
116         r.url        request.url
117         r.headers.merge!(request.headers)        if request.headers?
118         r.query    = request.querystring         if request.querystring?
119         r.body     = JSON.generate(request.body) if request.body?
120       end
121
122       Aviator::Response.send(:new, response, request)
123     end
124
125
126     def request_classes
127       @request_classes
128     end
129
130
131     private
132
133
134     def http_connection
135       @http_connection ||= Faraday.new do |conn|
136         conn.use     Logger.configure(log_file) if log_file
137         conn.adapter Faraday.default_adapter
138
139         conn.headers['Content-Type'] = 'application/json'
140       end
141     end
142
143
144     def load_requests
145       request_file_paths = provider_module.request_file_paths(service)
146       request_file_paths.each{ |path| require path }
147
148       constant_parts = request_file_paths \
149                         .map{|rf| rf.to_s.match(/#{provider}\/#{service}\/([\w\/]+)\.rb$/) } \
150                         .map{|rf| rf[1].split('/').map{|c| c.camelize }.join('::') }
151
152       @request_classes = constant_parts.map do |cp|
153         "Aviator::#{provider.camelize}::#{service.camelize}::#{cp}".constantize
154       end
155     end
156
157
158     def log_file
159       @log_file
160     end
161
162
163     def provider_module
164       @provider_module ||= "Aviator::#{provider.camelize}::Provider".constantize
165     end
166
167   end
168
169 end