apimatic_core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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