mastercard_core_sdk 1.1.3

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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +24 -0
  3. data/README.md +66 -0
  4. data/lib/mastercard_core_sdk/api/access_token_api.rb +31 -0
  5. data/lib/mastercard_core_sdk/api/request_token_api.rb +30 -0
  6. data/lib/mastercard_core_sdk/client/api_client.rb +192 -0
  7. data/lib/mastercard_core_sdk/constants/constants.rb +95 -0
  8. data/lib/mastercard_core_sdk/converters/encoded_url_converter.rb +55 -0
  9. data/lib/mastercard_core_sdk/converters/json_converter.rb +107 -0
  10. data/lib/mastercard_core_sdk/converters/sdk_converter_factory.rb +57 -0
  11. data/lib/mastercard_core_sdk/converters/xml_converter.rb +52 -0
  12. data/lib/mastercard_core_sdk/core/api_config.rb +18 -0
  13. data/lib/mastercard_core_sdk/core/api_config_builder.rb +48 -0
  14. data/lib/mastercard_core_sdk/core/configuration.rb +81 -0
  15. data/lib/mastercard_core_sdk/core/mastercard_api_configuration.rb +100 -0
  16. data/lib/mastercard_core_sdk/core/mastercard_authenticator.rb +25 -0
  17. data/lib/mastercard_core_sdk/core/query_params.rb +23 -0
  18. data/lib/mastercard_core_sdk/core/request_response_logger.rb +101 -0
  19. data/lib/mastercard_core_sdk/core/service_request.rb +24 -0
  20. data/lib/mastercard_core_sdk/exceptions/error_handler.rb +130 -0
  21. data/lib/mastercard_core_sdk/exceptions/sdk_base_error.rb +28 -0
  22. data/lib/mastercard_core_sdk/exceptions/sdk_conversion_error.rb +18 -0
  23. data/lib/mastercard_core_sdk/exceptions/sdk_oauth_error.rb +16 -0
  24. data/lib/mastercard_core_sdk/exceptions/sdk_response_error.rb +17 -0
  25. data/lib/mastercard_core_sdk/exceptions/sdk_validation_error.rb +16 -0
  26. data/lib/mastercard_core_sdk/interceptors/api_tracker_builder.rb +44 -0
  27. data/lib/mastercard_core_sdk/interceptors/logger_builder.rb +22 -0
  28. data/lib/mastercard_core_sdk/interceptors/signature_builder.rb +18 -0
  29. data/lib/mastercard_core_sdk/models/access_token_response.rb +150 -0
  30. data/lib/mastercard_core_sdk/models/detail.rb +165 -0
  31. data/lib/mastercard_core_sdk/models/details.rb +159 -0
  32. data/lib/mastercard_core_sdk/models/error.rb +212 -0
  33. data/lib/mastercard_core_sdk/models/error_response.rb +14 -0
  34. data/lib/mastercard_core_sdk/models/errors.rb +167 -0
  35. data/lib/mastercard_core_sdk/models/extension_point.rb +153 -0
  36. data/lib/mastercard_core_sdk/models/request_token_response.rb +169 -0
  37. data/lib/mastercard_core_sdk/oauth/oauth_parameters.rb +20 -0
  38. data/lib/mastercard_core_sdk/oauth/oauth_util.rb +205 -0
  39. data/lib/mastercard_core_sdk/tracker/api_tracker.rb +20 -0
  40. data/lib/mastercard_core_sdk/tracker/token_api_tracker.rb +52 -0
  41. data/lib/mastercard_core_sdk/version.rb +3 -0
  42. data/lib/mastercard_core_sdk.rb +65 -0
  43. metadata +208 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6e7df2eff37964c63a22e1236da3947f19a991b4
4
+ data.tar.gz: 76953aebb3f13d721632da658b251fdb04c678f5
5
+ SHA512:
6
+ metadata.gz: 098ae2e010fd9bd98a8711a9303fa69c3bf113fc10abe0be31976dd8bdd43c1de2d1ab1c4286b8680c13dc3b078fbd7f8d3ce3dc91e4aa92c1e9bde454f237ca
7
+ data.tar.gz: e756bba10eba20b7ef1c639fb9230ec42a6abce1c6c082f0be4e70a89f53a9e68dccac1e33b533c44ed2226e6f6186d4c5da9c2da8d70fdcae1826c359409b81
data/LICENSE.txt ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2016, MasterCard International Incorporated
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are
5
+ permitted provided that the following conditions are met:
6
+
7
+ Redistributions of source code must retain the above copyright notice, this list of
8
+ conditions and the following disclaimer.
9
+ Redistributions in binary form must reproduce the above copyright notice, this list of
10
+ conditions and the following disclaimer in the documentation and/or other materials
11
+ provided with the distribution.
12
+ Neither the name of the MasterCard International Incorporated nor the names of its
13
+ contributors may be used to endorse or promote products derived from this software
14
+ without specific prior written permission.
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
16
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
18
+ SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
20
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
23
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
+ SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # MastercardCoreSdk
2
+ This is core SDK containing the configuration part for checkout SDK.
3
+ The merchant checkout SDK - MastercardMasterpassMerchant requires this MastercardCoreSdk as dependency for calling the checkout API services.
4
+ Features include :
5
+ • Exception Handler - Exception handling features help you deal with any unexpected or exceptional situations that occur while calling the API services.
6
+ • Serializers - Serializer handles the request and responses for the API services.
7
+ • ApiTracker - ApiTracker tracks the details of SDK from which API services are called.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'mastercard_core_sdk'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install mastercard_core_sdk
24
+
25
+ ## Usage
26
+ Set MasterCard Configuration using Consumer Key & Private Key from developer's site and call API:
27
+
28
+ ```
29
+ require 'mastercard_core_sdk'
30
+
31
+ MasterCardApiConfiguration.consumer_key = <Consumer Key>
32
+ MasterCardApiConfiguration.private_key = OpenSSL::PKCS12.new(File.open(<Path to P12 file>), <Password>).key
33
+ MasterCardApiConfiguration.sandbox = false #By default SANDBOX environment is set, Set sandbox to false to use Production environment
34
+
35
+ request_token_response = RequestTokenApi.create(<URL>)
36
+ ```
37
+
38
+
39
+ ## Copyright
40
+ Copyright (c) 2016, MasterCard International Incorporated. See LICENSE for details.
41
+
42
+ ## LICENSE
43
+ Copyright (c) 2016, MasterCard International Incorporated. All rights reserved.
44
+
45
+ Redistribution and use in source and binary forms, with or without modification, are
46
+ permitted provided that the following conditions are met:
47
+
48
+ Redistributions of source code must retain the above copyright notice, this list of
49
+ conditions and the following disclaimer.
50
+ Redistributions in binary form must reproduce the above copyright notice, this list of
51
+ conditions and the following disclaimer in the documentation and/or other materials
52
+ provided with the distribution.
53
+ Neither the name of the MasterCard International Incorporated nor the names of its
54
+ contributors may be used to endorse or promote products derived from this software
55
+ without specific prior written permission.
56
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
57
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
58
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
59
+ SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
60
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
61
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
62
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
63
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
64
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65
+ SUCH DAMAGE.
66
+
@@ -0,0 +1,31 @@
1
+ require_relative '../core/service_request'
2
+ require_relative '../client/api_client'
3
+ require_relative '../exceptions/error_handler'
4
+ require_relative '../models/access_token_response'
5
+
6
+ module MastercardCoreSdk
7
+ module Api
8
+ class AccessTokenApi
9
+ include MastercardCoreSdk::Core, MastercardCoreSdk::Client, MastercardCoreSdk::Exceptions, MastercardCoreSdk::Tracker
10
+
11
+ # Access Token Api service
12
+ # @param oauth_verifier
13
+ # @param oauth_token
14
+ # @param api_config Optional ApiConfig object.
15
+ # @return [AccessTokenResponse]
16
+ def self.create(oauth_verifier, oauth_token, api_config = nil)
17
+ path = "/oauth/consumer/v1/access_token"
18
+
19
+ service_request = ServiceRequest.new
20
+ service_request.headers = {"oauth_verifier" => oauth_verifier, "oauth_token" => oauth_token}
21
+ service_request.content_type = "application/xml"
22
+ api_client = ApiClient.new(api_config)
23
+
24
+ api_client.api_tracker = TokenApiTracker.new
25
+ api_client.error_handler = ErrorHandler.new
26
+ return api_client.call(path, service_request, "POST", AccessTokenResponse)
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ require_relative '../core/service_request'
2
+ require_relative '../client/api_client'
3
+ require_relative '../exceptions/error_handler'
4
+ require_relative '../models/request_token_response'
5
+
6
+ module MastercardCoreSdk
7
+ module Api
8
+ class RequestTokenApi
9
+ include MastercardCoreSdk::Core, MastercardCoreSdk::Client, MastercardCoreSdk::Exceptions, MastercardCoreSdk::Tracker
10
+
11
+ # Request Token Api service
12
+ # @param oauth_callback_url Callback URL.
13
+ # @param api_config Optional ApiConfig object.
14
+ # @return [RequestTokenResponse]
15
+ def self.create(oauth_callback_url, api_config = nil)
16
+ path = "/oauth/consumer/v1/request_token"
17
+
18
+ service_request = ServiceRequest.new
19
+ service_request.headers = {"oauth_callback" => oauth_callback_url}
20
+ service_request.content_type = "application/xml"
21
+ api_client = ApiClient.new(api_config)
22
+
23
+ api_client.api_tracker = TokenApiTracker.new
24
+ api_client.error_handler = ErrorHandler.new
25
+ return api_client.call(path, service_request, "POST", RequestTokenResponse)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,192 @@
1
+ require 'date'
2
+ require 'typhoeus'
3
+ require 'uri'
4
+ require 'logging'
5
+
6
+ require_relative '../models/error_response'
7
+ require_relative '../core/mastercard_authenticator'
8
+ require_relative '../core/mastercard_api_configuration'
9
+ require_relative '../core/api_config'
10
+ require_relative '../interceptors/signature_builder'
11
+ require_relative '../interceptors/logger_builder'
12
+ require_relative '../interceptors/api_tracker_builder'
13
+ require_relative '../converters/sdk_converter_factory'
14
+
15
+ module MastercardCoreSdk
16
+ module Client
17
+ class ApiClient
18
+ include MastercardCoreSdk::Core, MastercardCoreSdk::Interceptors, MastercardCoreSdk::Converters, MastercardCoreSdk::Tracker
19
+
20
+ @@logger = Logging.logger[self]
21
+
22
+ # The Configuration object holding settings to be used in the API client.
23
+ attr_accessor :config
24
+
25
+ # The ApiConfig object holding environment configurations.
26
+ attr_accessor :api_config
27
+
28
+ # Defines the headers to be used in HTTP requests of all API calls by default.
29
+ #
30
+ # @return [Hash]
31
+ attr_accessor :default_headers
32
+
33
+ # Defines the api_tracker to be added in request header having parameters.
34
+ #
35
+ # @return [Hash]
36
+ attr_accessor :api_tracker
37
+
38
+ # Defines the object that would handle error for all the requests.
39
+ attr_accessor :error_handler
40
+
41
+ attr_accessor :mastercard_authenticator
42
+
43
+ # Initializing Api Client with user-agent, configuration and default headers.
44
+ # Validating MasterCardApiConfiguration and calling interceptor for Authorization signature and logger.
45
+ def initialize(api_config = nil)
46
+ @config = Configuration.default
47
+ @user_agent = @config.user_agent
48
+ @default_headers = @config.default_headers
49
+
50
+ @mastercard_authenticator = MastercardAuthenticator.new
51
+ @api_config = api_config || MasterCardApiConfiguration.api_config
52
+ MasterCardApiConfiguration.validate_config(@api_config)
53
+ end
54
+
55
+ def self.default
56
+ @@default ||= ApiClient.new
57
+ end
58
+
59
+ # Execute Typhoeus request.
60
+ # @param path URL for request
61
+ # @param service_request Service Request object
62
+ # @param http_method Specifies HTTP method
63
+ # @param return_type Specifies response return type model
64
+ # @return [String]
65
+ def call(path, service_request, http_method, return_type)
66
+ request = build_request(http_method, path, service_request, @api_config)
67
+ response_body, response_code, response_headers = call_api(request, return_type)
68
+
69
+ return response_body
70
+ end
71
+
72
+ private
73
+ # Call an API with given options.
74
+ #
75
+ # @return [Array<(Object, Fixnum, Hash)>] an array of 3 elements:
76
+ # the data deserialized from response body (could be nil), response status code and response headers.
77
+ def call_api(request, return_type)
78
+ @mastercard_authenticator.api_tracker = @api_tracker
79
+ @mastercard_authenticator.authenticate
80
+ response = request.run
81
+
82
+ # Clearing callbacks
83
+ request.on_complete.clear
84
+ Typhoeus.before.clear
85
+
86
+ unless response.success?
87
+ error_response = ErrorResponse.new(:response => response, :response_code => response.response_code)
88
+ @error_handler.handle_error(error_response)
89
+ end
90
+
91
+ if return_type
92
+ converter = SDKConverterFactory.get_converter(mime_sub_type(response.headers['Content-Type']))
93
+ data = converter.response_body_converter(response.response_body, return_type)
94
+ else
95
+ data = nil
96
+ end
97
+
98
+ return data, response.code, response.headers
99
+ end
100
+
101
+ def build_request(http_method, path, request, api_config)
102
+ url = build_request_url(path, request, api_config)
103
+ http_method = http_method.to_sym.downcase
104
+ content_type_header = {"Content-Type" => request.content_type}
105
+ api_config_header = {ApiConfig::CONFIG_NAME_HEADER => @api_config.name}
106
+ header_params = @default_headers.merge(content_type_header || {}).merge(request.headers || {}).merge(api_config_header)
107
+ query_params = request.query_params || {}
108
+
109
+ req_opts = {
110
+ :method => http_method,
111
+ :headers => header_params,
112
+ :params => query_params,
113
+ :timeout => @config.timeout,
114
+ :ssl_verifypeer => @config.verify_ssl
115
+ }
116
+
117
+ if [:post, :patch, :put, :delete].include?(http_method)
118
+ req_body = build_request_body(request)
119
+ req_opts.update :body => req_body
120
+ end
121
+
122
+ Typhoeus::Request.new(url, req_opts)
123
+ end
124
+
125
+ def build_request_url(path, service_request, api_config)
126
+ if service_request.path_params.length > 0
127
+ service_request.path_params.each do |param, value|
128
+ path = path.sub('{' + param + '}', value.to_s)
129
+ end
130
+ end
131
+ # Add leading and trailing slashes to path
132
+ path = "/#{path}".gsub(/\/+/, '/')
133
+ URI.encode(api_config.host_url + path)
134
+ end
135
+
136
+ def build_request_body(service_request)
137
+ content_type = service_request.content_type || nil
138
+ body = service_request.body || nil
139
+ data = nil
140
+ if body
141
+ converter = SDKConverterFactory.get_converter(mime_sub_type(content_type))
142
+ data = converter.request_body_converter(body)
143
+ end
144
+ return data
145
+ end
146
+
147
+ def user_agent=(user_agent)
148
+ @user_agent = user_agent
149
+ @default_headers['User-Agent'] = @user_agent
150
+ end
151
+
152
+
153
+ def mime_sub_type(content_type)
154
+ mime_type = ""
155
+ if json_mime?(content_type)
156
+ mime_type = JSON_MIME_TYPE
157
+ elsif xml_mime?(content_type)
158
+ mime_type = XML_MIME_TYPE
159
+ elsif urlencoded_mime?(content_type)
160
+ mime_type = URLENCODED_MIME_TYPE
161
+ end
162
+ return mime_type
163
+ end
164
+
165
+ # Check if the given MIME is a JSON MIME.
166
+ # JSON MIME examples:
167
+ # application/json
168
+ # application/json; charset=UTF8
169
+ # APPLICATION/JSON
170
+ def json_mime?(mime)
171
+ !!(mime =~ /\Aapplication\/json(;.*)?\z/i)
172
+ end
173
+
174
+ # Check if the given MIME is a XML MIME.
175
+ # XML MIME examples:
176
+ # application/xml
177
+ # application/xml; charset=UTF8
178
+ # APPLICATION/XML
179
+ def xml_mime?(mime)
180
+ !!(mime =~ /\Aapplication\/xml(;.*)?\z/i)
181
+ end
182
+
183
+ # Check if the given MIME is a X-WWW-FORM_URLENCODED MIME.
184
+ # XML MIME examples:
185
+ # application/x-www-form-urlencoded
186
+ def urlencoded_mime?(mime)
187
+ !!(mime =~ /\Aapplication\/x-www-form-urlencoded(;.*)?\z/i)
188
+ end
189
+
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,95 @@
1
+ module MastercardCoreSdk
2
+
3
+ #Constants defined for base SDK
4
+
5
+ #Header
6
+ API_TRACKER_HEADER = "API-Call-Tracker"
7
+ USER_AGENT_HEADER = "User-Agent"
8
+
9
+ #OAuth
10
+ OAUTH_BODY_HASH = 'oauth_body_hash'
11
+ OAUTH_CONSUMER_KEY = 'oauth_consumer_key'
12
+ OAUTH_NONCE = 'oauth_nonce'
13
+ OAUTH_SIGNATURE = 'oauth_signature'
14
+ OAUTH_SIGNATURE_METHOD = 'oauth_signature_method'
15
+ OAUTH_KEY_SIGNATURE_METHOD_VAL = 'RSA-SHA1'
16
+ OAUTH_TIMESTAMP = 'oauth_timestamp'
17
+ OAUTH_VERSION = 'oauth_version'
18
+ OAUTH_VERSION_VAL = '1.0'
19
+ OAUTH_KEY_TOKEN = 'oauth_token'
20
+ OAUTH_KEY_LONG_ACCESS_TOKEN = 'long_access_token'
21
+ OAUTH_KEY_ACCESS_TOKEN = 'access_token'
22
+ OAUTH_TOKEN = 'oauth_token'
23
+ OAUTH_VERIFIER = 'oauth_verifier'
24
+ OAUTH_TOKEN_SECRET = 'oauth_token_secret'
25
+ OAUTH_CALLBACK = 'oauth_callback'
26
+ OAUTH_CALLBACK_CONFIRMED = 'oauth_callback_confirmed'
27
+ OAUTH_EXPIRES_IN = 'oauth_expires_in'
28
+ REALM = 'realm'
29
+ REALM_TYPE = 'eWallet'
30
+ ORIGIN_URL = 'originUrl'
31
+ AUTH_HEADER = 'Authorization'
32
+
33
+ NONCE_LENGTH = 8
34
+ VALID_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
35
+
36
+ OAUTH_START_STRING = 'OAuth '
37
+ ERROR_STATUS_BOUNDARY = 300
38
+ EMPTY_STRING = ""
39
+
40
+ POST = "POST"
41
+ GET = "GET"
42
+ DELETE = "DELETE"
43
+ PUT = "PUT"
44
+ UTF_8 = "UTF-8"
45
+ EQUALS = "="
46
+ AMP = '&'
47
+ COLON_2X_BACKSLASH = "://"
48
+ MESSAGE = "Message"
49
+ HTTP_CODE = "HttpCode"
50
+
51
+ SSL_CA_CER_PATH_LOCATION = '/data/cert.pem'
52
+ BASE_SDK_VERSION = "base_sdk_version="
53
+ CLIENT_SDK_VERSION = "client_sdk_version="
54
+ LANG_NAME = "lang_name="
55
+ LANG_VERSION = "lang_version="
56
+ PLUGIN_VERSION = "plugin_version"
57
+ SEPERATOR = ","
58
+ EQUAL = "="
59
+ USER_AGENT = "MC Open API OAuth Framework v1.0-Ruby"
60
+
61
+ LOG_REQUEST = "Request: "
62
+ LOG_REQUEST_INFORMATION = "Request Information"
63
+ COLON = ": "
64
+ HYPHEN = " - "
65
+
66
+ LOG_RESPONSE = "Response: "
67
+ LOG_RESPONSE_INFORMATION= "Response Information"
68
+ LOG_URI = "Uri: "
69
+ LOG_CONTENT = "Content: "
70
+
71
+ LOG_MSG_TRACKING_INFO_ERROR = 'Tracking info method should be implemented for API Tracker.'
72
+ LOG_MSG_USER_AGENT_ERROR = 'User Agent info method should be implemented for API Tracker.'
73
+ LOG_MSG_OAUTH_HEADER = 'Authorization header added in the request.'
74
+ LOG_MSG_SANDBOX = "Routing to sandbox environment. Sandbox url: "
75
+
76
+ ERR_MSG_PRIVATE_KEY = "Private key must be set through MasterCardApiConfiguration class."
77
+ ERR_MSG_CONSUMER_KEY = "Consumer key must be set through MasterCardApiConfiguration class."
78
+ ERR_MSG_NULL_HEADER = "Found null value for API-Call-Tracker or User-Agent header."
79
+ ERR_MSG_NULL_SERVICE = "Found API tracker service is not implemented."
80
+ ERR_MSG_NULL_REQUEST = "Request can not be null."
81
+ ERR_MSG_NULL_RESPONSE = "Response can not be null."
82
+ ERR_MSG_OAUTH_HEADER = "Parameters can not be null."
83
+ ERR_MSG_CONVERSION = "Conversion failed."
84
+ ERR_MSG_API_CONFIG = "Api Config cannot be null."
85
+ ERR_MSG_HOST_URL = "Host URL cannot be empty."
86
+
87
+ NULL_RESPONSE_PARAMETERS_ERROR = "Response parameters cannot be null."
88
+ NULL_OAUTH_PARAMETERS_ERROR = "Oauth parameters cannot be null."
89
+
90
+ # Mime-types
91
+ JSON_MIME_TYPE = "JSON"
92
+ XML_MIME_TYPE = "XML"
93
+ URLENCODED_MIME_TYPE = "WWW-FORM-URLENCODED"
94
+
95
+ end
@@ -0,0 +1,55 @@
1
+ require 'logging'
2
+ require_relative '../exceptions/sdk_oauth_error'
3
+
4
+ module MastercardCoreSdk
5
+ module Converters
6
+ # Handles conversion for content-type : "application/x-www-form-urlencoded"
7
+ class EncodedURLConverter
8
+ include MastercardCoreSdk::Exceptions
9
+
10
+ @@logger = Logging.logger[self]
11
+
12
+ # Convert the request body to String.
13
+ # @param value Request body string
14
+ # @return [String] string representation of the value
15
+ def request_body_converter(value)
16
+ return nil if value.nil?
17
+ return value.to_s if !value.is_a?(String)
18
+ end
19
+
20
+ # Convert the response to the given return type.
21
+ # @param response String retrieved that is to be converted to object
22
+ # @param return_type Defines converted object type; examples: "RequestTokenResponse", "AccessTokenResponse"
23
+ # @return [Object]
24
+ def response_body_converter(response, return_type)
25
+ body = response
26
+ return nil if body.nil? || body.empty?
27
+
28
+ begin
29
+ object = return_type.new(parse_response_params(body))
30
+ return object
31
+ rescue => err
32
+ @@logger.error err.message
33
+ raise SDKConversionError.new(:error_message => err.message, :source => self.class)
34
+ end
35
+ end
36
+
37
+ private
38
+ def parse_response_params(response_params)
39
+ response_params_hash = {}
40
+ if response_params.empty?
41
+ raise SdkOAuthError.new(NULL_OAUTH_PARAMETERS_ERROR)
42
+ else
43
+ if response_params.is_a?(String) && response_params.match(/&/)
44
+ response_params_arr = response_params.split('&').compact
45
+ response_params_hash = Hash[response_params_arr.map {|param| param.include?('=') ? param.split('=') : param}] unless response_params_arr.empty?
46
+ return response_params_hash
47
+ else
48
+ raise SDKConversionError.new(:error_message => ERR_MSG_CONVERSION, :source => self.class)
49
+ end
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,107 @@
1
+ require 'logging'
2
+ require 'json'
3
+ require_relative '../exceptions/sdk_conversion_error'
4
+
5
+ module MastercardCoreSdk
6
+ module Converters
7
+ # Handles conversion for content-type : "application/json"
8
+ class JsonConverter
9
+ include MastercardCoreSdk::Exceptions
10
+
11
+ @@logger = Logging.logger[self]
12
+
13
+ # Convert object (array, hash, object, etc) to JSON.
14
+ # @param object to be converted into JSON string
15
+ # @return [String] JSON string representation of the object
16
+ def request_body_converter(object)
17
+ return nil if object.nil? || object.is_a?(String)
18
+ serialized_json = nil
19
+
20
+ begin
21
+ if object.is_a?(Array)
22
+ object_hash = object.map{|o| object_to_hash(o) }
23
+ else
24
+ object_hash = object_to_hash(object)
25
+ end
26
+ serialized_json = object_hash.to_json
27
+ return serialized_json
28
+
29
+ rescue => err
30
+ @@logger.error err.message
31
+ raise SDKConversionError.new(:error_message => err.message, :source => self.class)
32
+ end
33
+ end
34
+
35
+ # Convert the response to the given return type.
36
+ #
37
+ # @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
38
+ def response_body_converter(response, return_type)
39
+ body = response.body
40
+ return nil if body.nil? || body.empty?
41
+ begin
42
+ data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
43
+ rescue JSON::ParserError => e
44
+ if %w(String Date DateTime).include?(return_type.to_s)
45
+ data = body
46
+ else
47
+ @@logger.error e.message
48
+ raise SDKConversionError.new(:error_message => e.message, :source => self.class)
49
+ end
50
+ end
51
+ convert_to_type data, return_type
52
+ end
53
+
54
+ private
55
+
56
+ # Convert object(non-array) to hash.
57
+ # @param [Object] obj object to be converted into JSON string
58
+ # @return [String] JSON string representation of the object
59
+ def object_to_hash(obj)
60
+ if obj.respond_to?(:to_hash)
61
+ obj.to_hash
62
+ else
63
+ obj
64
+ end
65
+ end
66
+
67
+ # Convert data to the given return type.
68
+ def convert_to_type(data, return_type)
69
+ return nil if data.nil?
70
+ case return_type.to_s
71
+ when 'String'
72
+ data.to_s
73
+ when 'Integer'
74
+ data.to_i
75
+ when 'Float'
76
+ data.to_f
77
+ when 'BOOLEAN'
78
+ data == true
79
+ when 'DateTime'
80
+ # parse date time (expecting ISO 8601 format)
81
+ DateTime.parse data
82
+ when 'Date'
83
+ # parse date time (expecting ISO 8601 format)
84
+ Date.parse data
85
+ when 'Object'
86
+ # generic object, return directly
87
+ data
88
+ when /\AArray<(.+)>\z/
89
+ # e.g. Array<Pet>
90
+ sub_type = $1
91
+ data.map {|item| convert_to_type(item, sub_type) }
92
+ when /\AHash\<String, (.+)\>\z/
93
+ # e.g. Hash<String, Integer>
94
+ sub_type = $1
95
+ {}.tap do |hash|
96
+ data.each {|k, v| hash[k] = convert_to_type(v, sub_type) }
97
+ end
98
+ else
99
+ return_type.new.tap do |model|
100
+ model.build_from_hash data
101
+ end
102
+ end
103
+ end
104
+
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,57 @@
1
+ require 'logging'
2
+ require_relative '../exceptions/sdk_conversion_error'
3
+
4
+ module MastercardCoreSdk
5
+ module Converters
6
+ # Decides converter as per content-type of request/response.
7
+ class SDKConverterFactory
8
+
9
+ @@logger = Logging.logger[self]
10
+ @@content_handlers = {}
11
+
12
+ CONTENT_TYPE_XML = "XML"
13
+ CONTENT_TYPE_JSON = "JSON"
14
+ CONTENT_TYPE_URL_ENCODED = "WWW-FORM-URLENCODED"
15
+ ERR_MSG_CONTENT_TYPE = "Content-type is not supported :"
16
+
17
+ class << self
18
+ include MastercardCoreSdk::Exceptions
19
+
20
+ # Get converter as per content-type.
21
+ # @param content_type String specifying content-type for request.
22
+ # @return [Hash]
23
+ def get_converter(content_type)
24
+ converter = nil
25
+ if content_type
26
+ return @@content_handlers[content_type] if @@content_handlers.key?(content_type)
27
+ if content_type.include?(CONTENT_TYPE_XML)
28
+ converter = XmlConverter.new
29
+ elsif content_type.include?(CONTENT_TYPE_JSON)
30
+ converter = JsonConverter.new
31
+ elsif content_type.include?(CONTENT_TYPE_URL_ENCODED)
32
+ converter = EncodedURLConverter.new
33
+ else
34
+ @@logger.debug "#{ERR_MSG_CONTENT_TYPE} #{content_type}"
35
+ raise SDKConversionError.new(:error_message => "#{ERR_MSG_CONTENT_TYPE} #{content_type}", :source => self.class)
36
+ end
37
+ set_converter(content_type, converter)
38
+ return converter
39
+ end
40
+ end
41
+
42
+ # Set the converter as per content-type.
43
+ # @param content_type Content-Type for request.
44
+ # @param converter specifies appropriate converter for the content-type.
45
+ def set_converter(content_type, converter)
46
+ if @@content_handlers.key?(content_type)
47
+ @@content_handlers[content_type] = converter
48
+ else
49
+ @@content_handlers.merge!({content_type => converter})
50
+ end
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
57
+