apimatic_core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/README.md +101 -0
  4. data/lib/apimatic-core/api_call.rb +103 -0
  5. data/lib/apimatic-core/authentication/header_auth.rb +21 -0
  6. data/lib/apimatic-core/authentication/multiple/and_auth_group.rb +28 -0
  7. data/lib/apimatic-core/authentication/multiple/auth_group.rb +45 -0
  8. data/lib/apimatic-core/authentication/multiple/or_auth_group.rb +29 -0
  9. data/lib/apimatic-core/authentication/multiple/single_auth.rb +48 -0
  10. data/lib/apimatic-core/authentication/query_auth.rb +21 -0
  11. data/lib/apimatic-core/configurations/global_configuration.rb +149 -0
  12. data/lib/apimatic-core/exceptions/invalid_auth_credential.rb +5 -0
  13. data/lib/apimatic-core/factories/http_response_factory.rb +14 -0
  14. data/lib/apimatic-core/http/configurations/http_client_configuration.rb +32 -0
  15. data/lib/apimatic-core/http/request/http_request.rb +50 -0
  16. data/lib/apimatic-core/http/response/api_response.rb +35 -0
  17. data/lib/apimatic-core/http/response/http_response.rb +24 -0
  18. data/lib/apimatic-core/logger/endpoint_logger.rb +28 -0
  19. data/lib/apimatic-core/request_builder.rb +361 -0
  20. data/lib/apimatic-core/response_handler.rb +269 -0
  21. data/lib/apimatic-core/types/error_case.rb +37 -0
  22. data/lib/apimatic-core/types/parameter.rb +116 -0
  23. data/lib/apimatic-core/types/sdk/api_exception.rb +15 -0
  24. data/lib/apimatic-core/types/sdk/base_model.rb +22 -0
  25. data/lib/apimatic-core/types/sdk/file_wrapper.rb +11 -0
  26. data/lib/apimatic-core/types/sdk/validation_exception.rb +10 -0
  27. data/lib/apimatic-core/types/xml_attributes.rb +37 -0
  28. data/lib/apimatic-core/utilities/api_helper.rb +551 -0
  29. data/lib/apimatic-core/utilities/auth_helper.rb +49 -0
  30. data/lib/apimatic-core/utilities/comparison_helper.rb +77 -0
  31. data/lib/apimatic-core/utilities/date_time_helper.rb +126 -0
  32. data/lib/apimatic-core/utilities/file_helper.rb +21 -0
  33. data/lib/apimatic-core/utilities/xml_helper.rb +215 -0
  34. data/lib/apimatic_core.rb +44 -0
  35. metadata +215 -0
@@ -0,0 +1,50 @@
1
+ module CoreLibrary
2
+ # An http request.
3
+ class HttpRequest
4
+ attr_accessor :http_method, :query_url, :headers,
5
+ :parameters, :username, :password,
6
+ :context
7
+
8
+ # The constructor.
9
+ # @param [HttpMethodEnum] http_method The HTTP method.
10
+ # @param [String] query_url The URL to send the request to.
11
+ # @param [Hash, Optional] headers The headers for the HTTP Request.
12
+ # @param [Hash, Optional] parameters The parameters for the HTTP Request.
13
+ # @param [Hash, Optional] context The context for the HTTP Request.
14
+ def initialize(http_method,
15
+ query_url,
16
+ headers: {},
17
+ parameters: {},
18
+ context: {})
19
+ @http_method = http_method
20
+ @query_url = query_url
21
+ @headers = headers
22
+ @parameters = parameters
23
+ @context = context
24
+ end
25
+
26
+ # Add a header to the HttpRequest.
27
+ # @param [String] name The name of the header.
28
+ # @param [String] value The value of the header.
29
+ def add_header(name, value)
30
+ @headers[name] = value
31
+ end
32
+
33
+ # Add a parameter to the HttpRequest.
34
+ # @param [String] name The name of the parameter.
35
+ # @param [String] value The value of the parameter.
36
+ def add_parameter(name, value)
37
+ @parameters[name] = value
38
+ end
39
+
40
+ # Add a query parameter to the HttpRequest.
41
+ # @param [String] name The name of the query parameter.
42
+ # @param [String] value The value of the query parameter.
43
+ def add_query_parameter(name, value)
44
+ @query_url = ApiHelper.append_url_with_query_parameters(@query_url,
45
+ { name => value },
46
+ ArraySerializationFormat::INDEXED)
47
+ @query_url = ApiHelper.clean_url(@query_url)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,35 @@
1
+ # Http response received.
2
+ module CoreLibrary
3
+ # The class to hold the complete HTTP response.
4
+ class ApiResponse
5
+ attr_reader :status_code, :reason_phrase, :headers, :raw_body, :request,
6
+ :data, :errors
7
+
8
+ # The constructor
9
+ # @param [HttpResponse] The original, raw response from the api.
10
+ # @param [Object] The data field specified for the response.
11
+ # @param [Array<String>] Any errors returned by the server.
12
+
13
+ def initialize(http_response,
14
+ data: nil,
15
+ errors: nil)
16
+ @status_code = http_response.status_code
17
+ @reason_phrase = http_response.reason_phrase
18
+ @headers = http_response.headers
19
+ @raw_body = http_response.raw_body
20
+ @request = http_response.request
21
+ @data = data
22
+ @errors = errors
23
+ end
24
+
25
+ # Returns true if status_code is between 200-300
26
+ def success?
27
+ status_code >= 200 && status_code < 300
28
+ end
29
+
30
+ # Returns true if status_code is between 400-600
31
+ def error?
32
+ status_code >= 400 && status_code < 600
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,24 @@
1
+ module CoreLibrary
2
+ # Http response received.
3
+ class HttpResponse
4
+ attr_reader :status_code, :reason_phrase, :headers, :raw_body, :request
5
+
6
+ # The constructor
7
+ # @param [Integer] status_code The status code returned by the server.
8
+ # @param [String] reason_phrase The reason phrase returned by the server.
9
+ # @param [Hash] headers The headers sent by the server in the response.
10
+ # @param [String] raw_body The raw body of the response.
11
+ # @param [HttpRequest] request The request that resulted in this response.
12
+ def initialize(status_code,
13
+ reason_phrase,
14
+ headers,
15
+ raw_body,
16
+ request)
17
+ @status_code = status_code
18
+ @reason_phrase = reason_phrase
19
+ @headers = headers
20
+ @raw_body = raw_body
21
+ @request = request
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module CoreLibrary
2
+ # This class is responsible for logging info messages, debug messages, and errors.
3
+ class EndpointLogger
4
+ attr_reader :logger
5
+
6
+ def initialize(logger)
7
+ @logger = logger
8
+ end
9
+
10
+ # Logs the info message.
11
+ # @param [String] info_message The message to be logged.
12
+ def info(info_message)
13
+ @logger&.info(info_message)
14
+ end
15
+
16
+ # Logs the debug message.
17
+ # @param [String] debug_message The message to be logged.
18
+ def debug(debug_message)
19
+ @logger&.debug(debug_message)
20
+ end
21
+
22
+ # Logs the error.
23
+ # @param [Exception] error The exception to be logged.
24
+ def error(error)
25
+ @logger&.error(error)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,361 @@
1
+ module CoreLibrary
2
+ # This class is the builder of the http request for an API call.
3
+ class RequestBuilder
4
+ def initialize
5
+ @server = nil
6
+ @path = nil
7
+ @http_method = nil
8
+ @template_params = {}
9
+ @header_params = {}
10
+ @query_params = {}
11
+ @form_params = {}
12
+ @additional_form_params = {}
13
+ @additional_query_params = {}
14
+ @multipart_params = {}
15
+ @body_param = nil
16
+ @should_wrap_body_param = nil
17
+ @body_serializer = nil
18
+ @auth = nil
19
+ @array_serialization_format = ArraySerializationFormat::INDEXED
20
+ @xml_attributes = nil
21
+ @endpoint_name_for_logging = nil
22
+ @endpoint_logger = nil
23
+ @template_validation_array = []
24
+ end
25
+
26
+ # The setter for the server.
27
+ # @param [string] server The server to use for the API call.
28
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
29
+ def server(server)
30
+ @server = server
31
+ self
32
+ end
33
+
34
+ # The setter for the URI of the endpoint.
35
+ # @param [string] path The URI of the endpoint.
36
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
37
+ def path(path)
38
+ @path = path
39
+ self
40
+ end
41
+
42
+ # The setter for the http method of the request.
43
+ # @param [HttpMethod] http_method The http method of the request.
44
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
45
+ def http_method(http_method)
46
+ @http_method = http_method
47
+ self
48
+ end
49
+
50
+ # The setter for the template parameter of the request.
51
+ # @param [Parameter] template_param The template parameter of the request.
52
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
53
+ def template_param(template_param)
54
+ template_param.validate
55
+ conditional_add_to_template_validation_array(template_param)
56
+ @template_params[template_param.get_key] = { 'value' => template_param.get_value,
57
+ 'encode' => template_param.need_to_encode }
58
+ self
59
+ end
60
+
61
+ # The setter for the header parameter to be sent in the request.
62
+ # @param [Parameter] header_param The header parameter to be sent in the request.
63
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
64
+ def header_param(header_param)
65
+ header_param.validate
66
+ conditional_add_to_template_validation_array(header_param)
67
+ @header_params[header_param.get_key] = header_param.get_value
68
+ self
69
+ end
70
+
71
+ # The setter for the query parameter to be sent in the request.
72
+ # @param [Parameter] query_param The query parameter to be sent in the request.
73
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
74
+ def query_param(query_param)
75
+ query_param.validate
76
+ conditional_add_to_template_validation_array(query_param)
77
+ @query_params[query_param.get_key] = query_param.get_value
78
+ self
79
+ end
80
+
81
+ # The setter for the form parameter to be sent in the request.
82
+ # @param [Parameter] form_param The form parameter to be sent in the request.
83
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
84
+ def form_param(form_param)
85
+ form_param.validate
86
+ conditional_add_to_template_validation_array(form_param)
87
+ @form_params[form_param.get_key] = form_param.get_value
88
+ self
89
+ end
90
+
91
+ # The setter for the additional form parameter to be sent in the request.
92
+ # @param [Hash] additional_form_params The additional form parameter to be sent in the request.
93
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
94
+ def additional_form_params(additional_form_params)
95
+ @additional_form_params = additional_form_params
96
+ self
97
+ end
98
+
99
+ # The setter for the additional query parameter to be sent in the request.
100
+ # @param [Hash] additional_query_params The additional query parameter to be sent in the request.
101
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
102
+ def additional_query_params(additional_query_params)
103
+ @additional_query_params = additional_query_params
104
+ self
105
+ end
106
+
107
+ # The setter for the multipart parameter to be sent in the request.
108
+ # @param [Parameter] multipart_param The multipart parameter to be sent in the request.
109
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
110
+ def multipart_param(multipart_param)
111
+ multipart_param.validate
112
+ conditional_add_to_template_validation_array(multipart_param)
113
+ @multipart_params[multipart_param.get_key] = get_part(multipart_param)
114
+ self
115
+ end
116
+
117
+ # The setter for the body parameter to be sent in the request.
118
+ # @param [Parameter] body_param The body parameter to be sent in the request.
119
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
120
+ def body_param(body_param)
121
+ body_param.validate
122
+ conditional_add_to_template_validation_array(body_param)
123
+ if !body_param.get_key.nil?
124
+ @body_param = {} if @body_param.nil?
125
+ @body_param[body_param.get_key] = body_param.get_value
126
+ else
127
+ @body_param = body_param.get_value
128
+ end
129
+ self
130
+ end
131
+
132
+ # The setter for the callable of serializing the body.
133
+ # @param [Callable] body_serializer The callable for serializing the body.
134
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
135
+ def body_serializer(body_serializer)
136
+ @body_serializer = body_serializer
137
+ self
138
+ end
139
+
140
+ # The setter for the auth to be used for the request.
141
+ # @param [Authentication] auth The instance of single or multiple auths.
142
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
143
+ def auth(auth)
144
+ @auth = auth
145
+ self
146
+ end
147
+
148
+ # The setter for the serialization format to be used for arrays in query or form parameters of the request.
149
+ # @param [ArraySerializationFormat] array_serialization_format The serialization format to be used for arrays.
150
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
151
+ def array_serialization_format(array_serialization_format)
152
+ @array_serialization_format = array_serialization_format
153
+ self
154
+ end
155
+
156
+ # The setter for the xml attributes to used while serialization of the xml body.
157
+ # @param [XmlAttribute] xml_attributes The xml attribute to used while serialization of the xml body.
158
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
159
+ def xml_attributes(xml_attributes)
160
+ @xml_attributes = xml_attributes
161
+ self
162
+ end
163
+
164
+ # The setter for the name of the endpoint controller method to used while logging an endpoint call.
165
+ # @param [String] endpoint_name_for_logging The name of the endpoint controller method to used while logging.
166
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
167
+ def endpoint_name_for_logging(endpoint_name_for_logging)
168
+ @endpoint_name_for_logging = endpoint_name_for_logging
169
+ self
170
+ end
171
+
172
+ # The setter for the name of the endpoint controller method to used while logging an endpoint call.
173
+ # @param [EndpointLogger] endpoint_logger The name of the endpoint controller method to used while logging.
174
+ # @return [RequestBuilder] An updated instance of RequestBuilder.
175
+ def endpoint_logger(endpoint_logger)
176
+ @endpoint_logger = endpoint_logger
177
+ self
178
+ end
179
+
180
+ # Sets global configuration object for the request builder.
181
+ def global_configuration(global_configuration)
182
+ @global_configuration = global_configuration
183
+ self
184
+ end
185
+
186
+ # Add param to the template validation array, in case a template is provided.
187
+ def conditional_add_to_template_validation_array(parameter)
188
+ return if parameter.get_template.nil?
189
+
190
+ @template_validation_array.push(parameter)
191
+ end
192
+
193
+ # Validates the template for the params provided with a template.
194
+ def validate_templates
195
+ return if @template_validation_array.nil? || @template_validation_array.empty?
196
+
197
+ @template_validation_array.each do |parameter|
198
+ parameter.validate_template(@global_configuration.get_sdk_module,
199
+ @global_configuration.should_symbolize_hash)
200
+ end
201
+ end
202
+
203
+ # Builds the Http Request.
204
+ # @param [Hash] endpoint_context The endpoint configuration to be used while executing the request.
205
+ # @return [HttpRequest] An instance of HttpRequest.
206
+ def build(endpoint_context)
207
+ validate_templates
208
+ _url = process_url
209
+ _request_body = process_body
210
+ _request_headers = process_headers(@global_configuration)
211
+ _http_request = HttpRequest.new(@http_method, _url,
212
+ headers: _request_headers,
213
+ parameters: _request_body,
214
+ context: endpoint_context)
215
+ apply_auth(@global_configuration.get_auth_managers, _http_request)
216
+
217
+ _http_request
218
+ end
219
+
220
+ # Processes and resolves the endpoint URL.
221
+ # @return [String] The processed URL.
222
+ def process_url
223
+ @endpoint_logger.info("Preparing query URL for #{@endpoint_name_for_logging}.")
224
+ _base_url = @global_configuration.get_base_uri_executor.call(@server)
225
+ _updated_url_with_template_params = ApiHelper.append_url_with_template_parameters(@path, @template_params)
226
+ _url = _base_url + _updated_url_with_template_params
227
+ _url = get_updated_url_with_query_params(_url)
228
+ ApiHelper.clean_url(_url)
229
+ end
230
+
231
+ # Returns the URL with resolved query parameters if any.
232
+ # @param [String] url The URL of the endpoint.
233
+ # @return [String] The URL with resolved query parameters if any.
234
+ def get_updated_url_with_query_params(url)
235
+ _has_additional_query_params = (!@additional_query_params.nil? and @additional_query_params.any?)
236
+ _has_query_params = (!@query_params.nil? and @query_params.any?)
237
+ _query_params = @query_params
238
+ _query_params.merge!(@additional_query_params) if _has_additional_query_params
239
+
240
+ if !_query_params.nil? && _query_params.any?
241
+ return ApiHelper.append_url_with_query_parameters(url,
242
+ _query_params,
243
+ @array_serialization_format)
244
+ end
245
+
246
+ url
247
+ end
248
+
249
+ # Processes all request headers (including local, global and additional).
250
+ # @param [GlobalConfiguration] global_configuration The global configuration to be used while processing the URL.
251
+ # @return [Hash] The processed request headers to be sent in the request.
252
+ def process_headers(global_configuration)
253
+ _request_headers = {}
254
+ _global_headers = global_configuration.get_global_headers
255
+ _additional_headers = global_configuration.get_additional_headers
256
+
257
+ _has_global_headers = (!_global_headers.nil? && _global_headers.any?)
258
+ _has_additional_headers = (!_additional_headers.nil? && _additional_headers.any?)
259
+ _has_local_headers = (!@header_params.nil? and @header_params.any?)
260
+
261
+ if _has_global_headers || _has_additional_headers || _has_local_headers
262
+ @endpoint_logger.info("Preparing headers for #{@endpoint_name_for_logging}.")
263
+ end
264
+
265
+ _request_headers.merge!(_global_headers) if _has_global_headers
266
+ _request_headers.merge!(_additional_headers) if _has_additional_headers
267
+
268
+ if _has_local_headers
269
+ ApiHelper.clean_hash(@header_params)
270
+ _request_headers.merge!(@header_params)
271
+ end
272
+
273
+ _request_headers
274
+ end
275
+
276
+ # Processes the body parameter of the request (including form param, json body or xml body).
277
+ # @return [Object] The body param to be sent in the request.
278
+ def process_body
279
+ _has_form_params = (!@form_params.nil? && @form_params.any?)
280
+ _has_additional_form_params = (!@additional_form_params.nil? && @additional_form_params.any?)
281
+ _has_multipart_param = (!@multipart_params.nil? && @multipart_params.any?)
282
+ _has_body_param = !@body_param.nil?
283
+ _has_body_serializer = !@body_serializer.nil?
284
+ _has_xml_attributes = !@xml_attributes.nil?
285
+
286
+ if _has_form_params || _has_additional_form_params
287
+ @endpoint_logger.info("Preparing form parameters for #{@endpoint_name_for_logging}.")
288
+ elsif _has_body_param
289
+ @endpoint_logger.info("Preparing body parameters for #{@endpoint_name_for_logging}.")
290
+ end
291
+
292
+ if _has_xml_attributes
293
+ return process_xml_parameters
294
+ elsif _has_form_params || _has_additional_form_params || _has_multipart_param
295
+ _form_params = @form_params
296
+ _form_params.merge!(@form_params) if _has_form_params
297
+ _form_params.merge!(@multipart_params) if _has_multipart_param
298
+ _form_params.merge!(@additional_form_params) if _has_additional_form_params
299
+ # TODO: add Array serialization format support while writing the POC
300
+ return ApiHelper.form_encode_parameters(_form_params, @array_serialization_format)
301
+ elsif _has_body_param && _has_body_serializer
302
+ return @body_serializer.call(resolve_body_param)
303
+ elsif _has_body_param && !_has_body_serializer
304
+ return resolve_body_param
305
+ end
306
+
307
+ {}
308
+ end
309
+
310
+ # Processes the part of a multipart request and assign appropriate part value and its content-type.
311
+ # @param [Parameter] multipart_param The multipart parameter to be sent in the request.
312
+ # @return [UploadIO] The translated Faraday's UploadIO instance.
313
+ def get_part(multipart_param)
314
+ param_value = multipart_param.get_value
315
+ if param_value.is_a? FileWrapper
316
+ part = param_value.file
317
+ part_content_type = param_value.content_type
318
+ else
319
+ part = param_value
320
+ part_content_type = multipart_param.get_default_content_type
321
+ end
322
+ Faraday::UploadIO.new(part, part_content_type)
323
+ end
324
+
325
+ # Processes the XML body parameter.
326
+
327
+ # @return [String] The serialized xml body.
328
+ def process_xml_parameters
329
+ unless @xml_attributes.get_array_item_name.nil?
330
+ return @body_serializer.call(@xml_attributes.get_root_element_name,
331
+ @xml_attributes.get_array_item_name,
332
+ @xml_attributes.get_value)
333
+ end
334
+
335
+ @body_serializer.call(@xml_attributes.get_root_element_name, @xml_attributes.get_value)
336
+ end
337
+
338
+ # Resolves the body parameter to appropriate type.
339
+ # @return [Hash] The resolved body parameter as per the type.
340
+ def resolve_body_param
341
+ if !@body_param.nil? && @body_param.is_a?(FileWrapper)
342
+ @header_params['content-type'] = @body_param.content_type if !@body_param.file.nil? &&
343
+ !@body_param.content_type.nil?
344
+ @header_params['content-length'] = @body_param.file.size.to_s
345
+ return @body_param.file
346
+ elsif !@body_param.nil? && @body_param.is_a?(File)
347
+ @header_params['content-length'] = @body_param.size.to_s
348
+ end
349
+ @body_param
350
+ end
351
+
352
+ # Applies the configured auth onto the http request.
353
+ # @param [Hash] auth_managers The hash of auth managers.
354
+ # @param [HttpRequest] http_request The HTTP request on which the auth is to be applied.
355
+ def apply_auth(auth_managers, http_request)
356
+ is_valid_auth = @auth.with_auth_managers(auth_managers).valid unless @auth.nil?
357
+ @auth.apply(http_request) if is_valid_auth
358
+ raise InvalidAuthCredential, @auth.error_message if !@auth.nil? && !is_valid_auth
359
+ end
360
+ end
361
+ end