mastercard_core_sdk 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +24 -0
- data/README.md +66 -0
- data/lib/mastercard_core_sdk/api/access_token_api.rb +31 -0
- data/lib/mastercard_core_sdk/api/request_token_api.rb +30 -0
- data/lib/mastercard_core_sdk/client/api_client.rb +192 -0
- data/lib/mastercard_core_sdk/constants/constants.rb +95 -0
- data/lib/mastercard_core_sdk/converters/encoded_url_converter.rb +55 -0
- data/lib/mastercard_core_sdk/converters/json_converter.rb +107 -0
- data/lib/mastercard_core_sdk/converters/sdk_converter_factory.rb +57 -0
- data/lib/mastercard_core_sdk/converters/xml_converter.rb +52 -0
- data/lib/mastercard_core_sdk/core/api_config.rb +18 -0
- data/lib/mastercard_core_sdk/core/api_config_builder.rb +48 -0
- data/lib/mastercard_core_sdk/core/configuration.rb +81 -0
- data/lib/mastercard_core_sdk/core/mastercard_api_configuration.rb +100 -0
- data/lib/mastercard_core_sdk/core/mastercard_authenticator.rb +25 -0
- data/lib/mastercard_core_sdk/core/query_params.rb +23 -0
- data/lib/mastercard_core_sdk/core/request_response_logger.rb +101 -0
- data/lib/mastercard_core_sdk/core/service_request.rb +24 -0
- data/lib/mastercard_core_sdk/exceptions/error_handler.rb +130 -0
- data/lib/mastercard_core_sdk/exceptions/sdk_base_error.rb +28 -0
- data/lib/mastercard_core_sdk/exceptions/sdk_conversion_error.rb +18 -0
- data/lib/mastercard_core_sdk/exceptions/sdk_oauth_error.rb +16 -0
- data/lib/mastercard_core_sdk/exceptions/sdk_response_error.rb +17 -0
- data/lib/mastercard_core_sdk/exceptions/sdk_validation_error.rb +16 -0
- data/lib/mastercard_core_sdk/interceptors/api_tracker_builder.rb +44 -0
- data/lib/mastercard_core_sdk/interceptors/logger_builder.rb +22 -0
- data/lib/mastercard_core_sdk/interceptors/signature_builder.rb +18 -0
- data/lib/mastercard_core_sdk/models/access_token_response.rb +150 -0
- data/lib/mastercard_core_sdk/models/detail.rb +165 -0
- data/lib/mastercard_core_sdk/models/details.rb +159 -0
- data/lib/mastercard_core_sdk/models/error.rb +212 -0
- data/lib/mastercard_core_sdk/models/error_response.rb +14 -0
- data/lib/mastercard_core_sdk/models/errors.rb +167 -0
- data/lib/mastercard_core_sdk/models/extension_point.rb +153 -0
- data/lib/mastercard_core_sdk/models/request_token_response.rb +169 -0
- data/lib/mastercard_core_sdk/oauth/oauth_parameters.rb +20 -0
- data/lib/mastercard_core_sdk/oauth/oauth_util.rb +205 -0
- data/lib/mastercard_core_sdk/tracker/api_tracker.rb +20 -0
- data/lib/mastercard_core_sdk/tracker/token_api_tracker.rb +52 -0
- data/lib/mastercard_core_sdk/version.rb +3 -0
- data/lib/mastercard_core_sdk.rb +65 -0
- metadata +208 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'logging'
|
2
|
+
require 'roxml'
|
3
|
+
require_relative '../exceptions/sdk_conversion_error'
|
4
|
+
|
5
|
+
module MastercardCoreSdk
|
6
|
+
module Converters
|
7
|
+
# Handles conversion for content-type : "application/xml"
|
8
|
+
class XmlConverter
|
9
|
+
include ROXML
|
10
|
+
include MastercardCoreSdk::Exceptions
|
11
|
+
|
12
|
+
@@logger = Logging.logger[self]
|
13
|
+
|
14
|
+
# Convert object (array, hash, object, etc) to XML.
|
15
|
+
# @param object to be converted into XML string
|
16
|
+
# @return [String] XML string representation of the object
|
17
|
+
def request_body_converter(object)
|
18
|
+
return nil if object.nil?
|
19
|
+
begin
|
20
|
+
if object.respond_to?(:to_xml)
|
21
|
+
serialized_xml = object.to_xml.serialize(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML)
|
22
|
+
else
|
23
|
+
serialized_xml = object
|
24
|
+
end
|
25
|
+
return serialized_xml.to_s
|
26
|
+
rescue => err
|
27
|
+
@@logger.error err.message
|
28
|
+
raise SDKConversionError.new(:error_message => err.message, :source => self.class)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Convert the response XML string to the given return type of model.
|
33
|
+
# @param response XML string to be converted to object
|
34
|
+
# @param return_type specifies model; examples: "RequestTokenResponse", "AccessTokenResponse"
|
35
|
+
# @return [Object]
|
36
|
+
def response_body_converter(response, return_type)
|
37
|
+
body = response
|
38
|
+
|
39
|
+
return nil if body.nil? || body.empty?
|
40
|
+
|
41
|
+
begin
|
42
|
+
object = return_type.from_xml(body) if return_type.respond_to?(:from_xml)
|
43
|
+
return object
|
44
|
+
rescue => err
|
45
|
+
@@logger.error err.message
|
46
|
+
raise SDKConversionError.new(:error_message => err.message, :source => self.class)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MastercardCoreSdk
|
2
|
+
module Core
|
3
|
+
# Defines consumer key, private key from developer's site and name, host URL for environment other than sandbox/production.
|
4
|
+
class ApiConfig
|
5
|
+
|
6
|
+
CONFIG_NAME_HEADER = "__config_name__"
|
7
|
+
attr_accessor :name, :consumer_key, :private_key, :host_url
|
8
|
+
|
9
|
+
def initialize(name, consumer_key, private_key, host_url)
|
10
|
+
@name = name
|
11
|
+
@consumer_key = consumer_key
|
12
|
+
@private_key = private_key
|
13
|
+
@host_url = host_url
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module MastercardCoreSdk
|
2
|
+
module Core
|
3
|
+
# To be defined by application developer : environment name, consumer key, private key and host URL.
|
4
|
+
class ApiConfigBuilder
|
5
|
+
|
6
|
+
# Sets environment name
|
7
|
+
# @param name Environment.
|
8
|
+
# @return [ApiConfigBuilder]
|
9
|
+
def name(name)
|
10
|
+
@name = name
|
11
|
+
return self
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sets consumer key
|
15
|
+
# @param consumer_key Consumer key from developer's site.
|
16
|
+
# @return [ApiConfigBuilder]
|
17
|
+
def consumer_key(consumer_key)
|
18
|
+
@consumer_key = consumer_key
|
19
|
+
return self
|
20
|
+
end
|
21
|
+
|
22
|
+
# Sets private key
|
23
|
+
# @param private_key Private key from developer's site.
|
24
|
+
# @return [ApiConfigBuilder]
|
25
|
+
def private_key(private_key)
|
26
|
+
@private_key = private_key
|
27
|
+
return self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Sets host URL as per environment(Sandbox/Production)
|
31
|
+
# @param host_url Host URL for the environment.
|
32
|
+
# @return [ApiConfigBuilder]
|
33
|
+
def host_url(host_url)
|
34
|
+
@host_url = host_url
|
35
|
+
return self
|
36
|
+
end
|
37
|
+
|
38
|
+
# Register the ApiConfig with MasterCardApiConfiguration.
|
39
|
+
# @return [ApiConfig]
|
40
|
+
def build
|
41
|
+
api_config = ApiConfig.new(@name, @consumer_key, @private_key, @host_url)
|
42
|
+
MasterCardApiConfiguration.register_config(api_config)
|
43
|
+
return api_config
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module MastercardCoreSdk
|
4
|
+
module Core
|
5
|
+
class Configuration
|
6
|
+
# Defines url scheme
|
7
|
+
attr_accessor :scheme
|
8
|
+
|
9
|
+
# Defines url host
|
10
|
+
attr_accessor :host
|
11
|
+
|
12
|
+
# Defines url base path
|
13
|
+
attr_accessor :base_path
|
14
|
+
|
15
|
+
# The time limit for HTTP request in seconds.
|
16
|
+
# Default to 0 (never times out).
|
17
|
+
attr_accessor :timeout
|
18
|
+
|
19
|
+
### TLS/SSL
|
20
|
+
# Set this to false to skip verifying SSL certificate when calling API from https server.
|
21
|
+
# Default to true.
|
22
|
+
#
|
23
|
+
# @note Do NOT set it to false in production code, otherwise you would face multiple types of cryptographic attacks.
|
24
|
+
#
|
25
|
+
# @return [true, false]
|
26
|
+
attr_accessor :verify_ssl
|
27
|
+
|
28
|
+
attr_accessor :inject_format
|
29
|
+
|
30
|
+
attr_accessor :force_ending_format
|
31
|
+
|
32
|
+
attr_accessor :format, :user_agent, :default_headers
|
33
|
+
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@scheme = 'https'
|
37
|
+
@host = 'api.mastercard.com'
|
38
|
+
@base_path = ''
|
39
|
+
@timeout = 0
|
40
|
+
@verify_ssl = false #To be set to true for production
|
41
|
+
@inject_format = false
|
42
|
+
@force_ending_format = false
|
43
|
+
@format = ""
|
44
|
+
@default_headers = {}
|
45
|
+
|
46
|
+
yield(self) if block_given?
|
47
|
+
end
|
48
|
+
|
49
|
+
# The default Configuration object.
|
50
|
+
def self.default
|
51
|
+
@@default ||= Configuration.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def configure
|
55
|
+
yield(self) if block_given?
|
56
|
+
end
|
57
|
+
|
58
|
+
def scheme=(scheme)
|
59
|
+
# remove :// from scheme
|
60
|
+
@scheme = scheme.sub(/:\/\//, '')
|
61
|
+
end
|
62
|
+
|
63
|
+
def host=(host)
|
64
|
+
# remove http(s):// and anything after a slash
|
65
|
+
@host = host.sub(/https?:\/\//, '').split('/').first
|
66
|
+
end
|
67
|
+
|
68
|
+
def base_path=(base_path)
|
69
|
+
# Add leading and trailing slashes to base_path
|
70
|
+
@base_path = "/#{base_path}".gsub(/\/+/, '/')
|
71
|
+
@base_path = "" if @base_path == "/"
|
72
|
+
end
|
73
|
+
|
74
|
+
def base_url
|
75
|
+
url = "#{scheme}://#{[host, base_path].join('/').gsub(/\/+/, '/')}".sub(/\/+\z/, '')
|
76
|
+
URI.encode(url)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "logging"
|
2
|
+
require_relative '../exceptions/sdk_validation_error'
|
3
|
+
require_relative 'api_config_builder'
|
4
|
+
|
5
|
+
module MastercardCoreSdk
|
6
|
+
module Core
|
7
|
+
# Setting MasterCard API configuration parameters for API calls
|
8
|
+
class MasterCardApiConfiguration
|
9
|
+
|
10
|
+
@@logger = Logging.logger[self]
|
11
|
+
PROD_KEY = "__PROD__"
|
12
|
+
SANDBOX_KEY = "__SANDBOX__"
|
13
|
+
SANDBOX_URL = "https://sandbox.api.mastercard.com"
|
14
|
+
PROD_URL = "https://api.mastercard.com"
|
15
|
+
|
16
|
+
class << self
|
17
|
+
include MastercardCoreSdk::Exceptions
|
18
|
+
|
19
|
+
# Defines consumer key from developer site.
|
20
|
+
attr_accessor :consumer_key
|
21
|
+
|
22
|
+
# Defines private key from p12 file from developer site.
|
23
|
+
attr_accessor :private_key
|
24
|
+
|
25
|
+
# Defines additional_properties for plugin.
|
26
|
+
attr_accessor :additional_properties
|
27
|
+
|
28
|
+
# Defines Hash having environment name as key and api_config object as value.
|
29
|
+
attr_accessor :configs
|
30
|
+
|
31
|
+
# Determines if environment is Sandbox.
|
32
|
+
attr_accessor :sandbox
|
33
|
+
|
34
|
+
# Validates private key, consumer key and host_url for api_config.
|
35
|
+
# @raise [SDKValidationError] if validation fails
|
36
|
+
def validate_config(config)
|
37
|
+
if config.nil?
|
38
|
+
@@logger.error ERR_MSG_API_CONFIG
|
39
|
+
raise SDKValidationError.new(ERR_MSG_API_CONFIG)
|
40
|
+
end
|
41
|
+
if config.consumer_key.to_s.empty?
|
42
|
+
@@logger.error ERR_MSG_CONSUMER_KEY
|
43
|
+
raise SDKValidationError.new(ERR_MSG_CONSUMER_KEY)
|
44
|
+
end
|
45
|
+
if config.private_key.nil?
|
46
|
+
@@logger.error ERR_MSG_PRIVATE_KEY
|
47
|
+
raise SDKValidationError.new(ERR_MSG_PRIVATE_KEY)
|
48
|
+
end
|
49
|
+
if config.host_url.to_s.empty?
|
50
|
+
@@logger.error ERR_MSG_HOST_URL
|
51
|
+
raise SDKValidationError.new(ERR_MSG_HOST_URL)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Registers the API configuration.
|
56
|
+
# @param api_config The API configuration.
|
57
|
+
def register_config(api_config)
|
58
|
+
self.configs.merge!({ api_config.name => api_config })
|
59
|
+
end
|
60
|
+
|
61
|
+
# Check if environment is Sandbox.
|
62
|
+
# @return [Boolean]
|
63
|
+
def sandbox?
|
64
|
+
self.sandbox
|
65
|
+
end
|
66
|
+
|
67
|
+
# Determine api_config object.
|
68
|
+
# @param name The environment name.
|
69
|
+
# @return [ApiConfig]
|
70
|
+
def api_config(name = nil)
|
71
|
+
if name
|
72
|
+
return self.configs[name]
|
73
|
+
else
|
74
|
+
if sandbox?
|
75
|
+
@@sandbox.private_key(self.private_key)
|
76
|
+
@@sandbox.consumer_key(self.consumer_key)
|
77
|
+
return @@sandbox.build
|
78
|
+
else
|
79
|
+
@@production.private_key(self.private_key)
|
80
|
+
@@production.consumer_key(self.consumer_key)
|
81
|
+
return @@production.build
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
self.additional_properties = {}
|
88
|
+
self.configs = {}
|
89
|
+
self.sandbox = true
|
90
|
+
|
91
|
+
# Initialize builders hash with sandbox/production environment configurations.
|
92
|
+
@@builders = {}
|
93
|
+
@@sandbox = ApiConfigBuilder.new.name(SANDBOX_KEY).host_url(SANDBOX_URL)
|
94
|
+
@@production = ApiConfigBuilder.new.name(PROD_KEY).host_url(PROD_URL)
|
95
|
+
@@builders.merge!({ SANDBOX_KEY => @@sandbox })
|
96
|
+
@@builders.merge!({ PROD_KEY => @@production })
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "logging"
|
2
|
+
require "typhoeus"
|
3
|
+
|
4
|
+
require_relative '../interceptors/signature_builder'
|
5
|
+
require_relative '../interceptors/logger_builder'
|
6
|
+
require_relative '../interceptors/api_tracker_builder'
|
7
|
+
|
8
|
+
module MastercardCoreSdk
|
9
|
+
module Core
|
10
|
+
# Setting MasterCard API configuration parameters for API calls
|
11
|
+
class MastercardAuthenticator
|
12
|
+
include MastercardCoreSdk::Interceptors
|
13
|
+
|
14
|
+
attr_accessor :api_tracker
|
15
|
+
|
16
|
+
def authenticate
|
17
|
+
Typhoeus.before do |request|
|
18
|
+
SignatureBuilder.build(request)
|
19
|
+
ApiTrackerBuilder.new(@api_tracker, request)
|
20
|
+
LoggerBuilder.log(request)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module MastercardCoreSdk
|
2
|
+
module Core
|
3
|
+
class QueryParams
|
4
|
+
|
5
|
+
attr_reader :params
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@params = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def add(key, value)
|
12
|
+
key = key.to_sym if key.is_a?(String)
|
13
|
+
@params.merge!({ key => value })
|
14
|
+
return self
|
15
|
+
end
|
16
|
+
|
17
|
+
def params
|
18
|
+
@params
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require "logging"
|
3
|
+
require_relative '../exceptions/sdk_validation_error'
|
4
|
+
|
5
|
+
module MastercardCoreSdk
|
6
|
+
module Core
|
7
|
+
# Class for defining log statements; it is called by logging interceptor for logging.
|
8
|
+
class RequestResponseLogger
|
9
|
+
include MastercardCoreSdk::Exceptions
|
10
|
+
|
11
|
+
NEWLINE = "\n"
|
12
|
+
@@logger = Logging.logger[self]
|
13
|
+
|
14
|
+
# Method called by interceptor to log request
|
15
|
+
def self.log_request(request)
|
16
|
+
if request
|
17
|
+
|
18
|
+
log_str = LOG_REQUEST_INFORMATION
|
19
|
+
request_api_info = NEWLINE + LOG_REQUEST + request.options[:method].to_s.upcase + HYPHEN + request.base_url + NEWLINE
|
20
|
+
log_str += request_api_info
|
21
|
+
|
22
|
+
headers = request.options[:headers]
|
23
|
+
body = request.options[:body]
|
24
|
+
|
25
|
+
if headers && headers.size > 0
|
26
|
+
headers.each do |param,value|
|
27
|
+
log_str += NEWLINE + param.to_s + COLON + value.to_s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if body
|
32
|
+
log_str += NEWLINE + body.to_s
|
33
|
+
end
|
34
|
+
log_str += NEWLINE
|
35
|
+
|
36
|
+
@@logger.info request_api_info
|
37
|
+
@@logger.debug log_str
|
38
|
+
else
|
39
|
+
@@logger.error ERR_MSG_NULL_REQUEST
|
40
|
+
raise SDKValidationError.new(ERR_MSG_NULL_REQUEST)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Method called by interceptor to log response
|
45
|
+
def self.log_response(response)
|
46
|
+
if response
|
47
|
+
|
48
|
+
log_str = NEWLINE + LOG_RESPONSE_INFORMATION
|
49
|
+
|
50
|
+
response_api_info = NEWLINE + LOG_RESPONSE + response.return_message + HYPHEN + response.return_code.to_s.upcase + HYPHEN + response.code.to_s.upcase
|
51
|
+
response_uri_info = NEWLINE + LOG_URI + HYPHEN + response.options[:effective_url]
|
52
|
+
|
53
|
+
log_str += response_api_info + response_uri_info
|
54
|
+
headers = response.headers
|
55
|
+
|
56
|
+
if headers && headers.size > 0
|
57
|
+
headers.each do |param, value|
|
58
|
+
if value.is_a?(Array)
|
59
|
+
value.each do |v|
|
60
|
+
log_str += NEWLINE + param + COLON + v
|
61
|
+
end
|
62
|
+
else
|
63
|
+
log_str += NEWLINE + param + COLON + value
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if response.response_body
|
69
|
+
response_body = response.response_body
|
70
|
+
|
71
|
+
xml_mime = !!(response.headers['Content-Type'] =~ /\Aapplication\/xml(;.*)?\z/i)
|
72
|
+
if xml_mime && response_body.include?("AccountNumber")
|
73
|
+
response_body = mask_data(response_body)
|
74
|
+
end
|
75
|
+
|
76
|
+
log_str += NEWLINE + response_body.to_s
|
77
|
+
end
|
78
|
+
log_str += NEWLINE
|
79
|
+
|
80
|
+
@@logger.info response_api_info
|
81
|
+
@@logger.debug log_str
|
82
|
+
else
|
83
|
+
@@logger.error ERR_MSG_NULL_RESPONSE
|
84
|
+
raise SDKValidationError.new(ERR_MSG_NULL_RESPONSE)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def self.mask_data(response_body)
|
91
|
+
xmldoc = Nokogiri::XML(response_body)
|
92
|
+
xmldoc.at("Card").search("AccountNumber").each do |node|
|
93
|
+
node.content = node.content.gsub(/.(?=\d{4})/,'*')
|
94
|
+
end
|
95
|
+
response_body = xmldoc.serialize(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML).sub("\n","").strip
|
96
|
+
return response_body
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MastercardCoreSdk
|
2
|
+
module Core
|
3
|
+
class ServiceRequest
|
4
|
+
|
5
|
+
attr_accessor :headers, :path_params, :query_params, :body, :content_type
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@headers = {}
|
9
|
+
@path_params = {}
|
10
|
+
@query_params = {}
|
11
|
+
end
|
12
|
+
|
13
|
+
# Set request path parameters
|
14
|
+
# @param query_params Hash specifying request query parameters
|
15
|
+
# @return [Hash]
|
16
|
+
def query_params=(query_params)
|
17
|
+
if query_params && query_params.params
|
18
|
+
query_params.params.map{|hash| @query_params.merge!(hash)}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require 'logging'
|
2
|
+
|
3
|
+
require_relative '../converters/sdk_converter_factory'
|
4
|
+
require_relative '../exceptions/sdk_response_error'
|
5
|
+
require_relative '../exceptions/sdk_conversion_error'
|
6
|
+
|
7
|
+
module MastercardCoreSdk
|
8
|
+
module Exceptions
|
9
|
+
# Raises custom errors as per error response details.
|
10
|
+
class ErrorHandler
|
11
|
+
include MastercardCoreSdk::Converters
|
12
|
+
|
13
|
+
@@logger = Logging.logger[self]
|
14
|
+
|
15
|
+
ERR_DESC_NULL_RES = "Received null response: "
|
16
|
+
ERR_DESC_EMPTY_RES = "Received empty body: "
|
17
|
+
ERR_REASON_NULL_RES = "NULL_RESPONSE"
|
18
|
+
ERR_REASON_EMPTY_BODY_RES = "EMPTY_BODY"
|
19
|
+
ERR_REASON_INVALID_RES = "INVALID_RESPONSE"
|
20
|
+
ERR_REASON_NT_TIMEOUT = "NETWORK_TIMEOUT"
|
21
|
+
ERR_MSG_INVALID_RES = "Received invalid response: ["
|
22
|
+
ERR_MSG_UNKN_RES = "Unknown reason for failure, please check logs."
|
23
|
+
ERR_SRC_UNKN = "Unknown"
|
24
|
+
ERR_NETWORK = "NETWORK_ERROR"
|
25
|
+
ERR_UNKN_REASON = "GENERAL_ERROR"
|
26
|
+
ERR_INTERNAL = "INTERNAL_PROCESSING_ERROR"
|
27
|
+
SEP_COLON = "]: "
|
28
|
+
OAUTH_MIME_TYPE = "WWW-FORM-URLENCODED"
|
29
|
+
ERR_MSG_RES_PARSE = "Exception occurred during response parsing."
|
30
|
+
|
31
|
+
# Raise custom error as per response error object.
|
32
|
+
# @param error_response The Typheous::Response object containing error details.
|
33
|
+
# @raise [SDKResponseError]
|
34
|
+
def handle_error(error_response)
|
35
|
+
errors = nil
|
36
|
+
response_body = error_response.response.response_body
|
37
|
+
response_status_code = error_response.response_code
|
38
|
+
|
39
|
+
if response_body.empty?
|
40
|
+
errors = get_errors_object(ERR_DESC_EMPTY_RES, ERR_REASON_EMPTY_BODY_RES, ERR_SRC_UNKN)
|
41
|
+
@@logger.error "400 #{ERR_SRC_UNKN}"
|
42
|
+
raise SDKResponseError.new(:errors_object => errors, :status_code => 400)
|
43
|
+
|
44
|
+
elsif response_status_code == 200
|
45
|
+
# In some cases, response code is 200 and response body is empty.
|
46
|
+
# Received response, but could not be matched to the appropriate response object.
|
47
|
+
description = ERR_MSG_INVALID_RES + response_body + SEP_COLON
|
48
|
+
errors = get_errors_object(description, ERR_REASON_INVALID_RES, ERR_SRC_UNKN)
|
49
|
+
@@logger.error "400 #{ERR_MSG_INVALID_RES}"
|
50
|
+
raise SDKResponseError.new(:errors_object => errors, :status_code => 400)
|
51
|
+
end
|
52
|
+
|
53
|
+
content_type = mime_sub_type(error_response.response.headers['Content-Type']) rescue nil
|
54
|
+
|
55
|
+
begin
|
56
|
+
converter = SDKConverterFactory.get_converter(content_type)
|
57
|
+
errors = converter.response_body_converter(response_body, Errors)
|
58
|
+
raise SDKResponseError.new(:errors_object => errors, :status_code => response_status_code)
|
59
|
+
|
60
|
+
rescue SDKConversionError => err
|
61
|
+
# For request and access token call if any require parameter missing in header server send response as encodedURL.
|
62
|
+
# Below code set the received response as description and raise Errors object.
|
63
|
+
if content_type.include?(OAUTH_MIME_TYPE)
|
64
|
+
description = response_body
|
65
|
+
else
|
66
|
+
description = err.message
|
67
|
+
end
|
68
|
+
|
69
|
+
case response_status_code
|
70
|
+
when 400
|
71
|
+
errors = get_errors_object(description, nil, "")
|
72
|
+
when 502
|
73
|
+
# Request timeout
|
74
|
+
errors = get_errors_object(description, ERR_REASON_NT_TIMEOUT, ERR_NETWORK)
|
75
|
+
else
|
76
|
+
# Unknown error
|
77
|
+
errors = get_errors_object(ERR_MSG_UNKN_RES, ERR_UNKN_REASON, ERR_SRC_UNKN)
|
78
|
+
end
|
79
|
+
@@logger.error "#{response_status_code}\n#{errors.error}"
|
80
|
+
raise SDKResponseError.new(:errors_object => errors, :status_code => response_status_code)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def get_errors_object(description, reason_code, source)
|
87
|
+
error = Error.new(:description => description, :reason_code => reason_code, :source => source, :recoverable => false)
|
88
|
+
return Errors.new(:error => [error])
|
89
|
+
end
|
90
|
+
|
91
|
+
def mime_sub_type(content_type)
|
92
|
+
mime_type = ""
|
93
|
+
if json_mime?(content_type)
|
94
|
+
mime_type = JSON_MIME_TYPE
|
95
|
+
elsif xml_mime?(content_type)
|
96
|
+
mime_type = XML_MIME_TYPE
|
97
|
+
elsif urlencoded_mime?(content_type)
|
98
|
+
mime_type = URLENCODED_MIME_TYPE
|
99
|
+
end
|
100
|
+
return mime_type
|
101
|
+
end
|
102
|
+
|
103
|
+
# Check if the given MIME is a JSON MIME.
|
104
|
+
# JSON MIME examples:
|
105
|
+
# application/json
|
106
|
+
# application/json; charset=UTF8
|
107
|
+
# APPLICATION/JSON
|
108
|
+
def json_mime?(mime)
|
109
|
+
!!(mime =~ /\Aapplication\/json(;.*)?\z/i)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Check if the given MIME is a XML MIME.
|
113
|
+
# XML MIME examples:
|
114
|
+
# application/xml
|
115
|
+
# application/xml; charset=UTF8
|
116
|
+
# APPLICATION/XML
|
117
|
+
def xml_mime?(mime)
|
118
|
+
!!(mime =~ /\Aapplication\/xml(;.*)?\z/i)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Check if the given MIME is a X-WWW-FORM_URLENCODED MIME.
|
122
|
+
# XML MIME examples:
|
123
|
+
# application/x-www-form-urlencoded
|
124
|
+
def urlencoded_mime?(mime)
|
125
|
+
!!(mime =~ /\Aapplication\/x-www-form-urlencoded(;.*)?\z/i)
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module MastercardCoreSdk
|
2
|
+
module Exceptions
|
3
|
+
# Defines base error class for all the custom errors.
|
4
|
+
class SDKBaseError < RuntimeError
|
5
|
+
attr_accessor :errors_object, :status_code, :error_message
|
6
|
+
# Usage examples:
|
7
|
+
# SDKBaseError.new
|
8
|
+
# SDKBaseError.new("message")
|
9
|
+
# SDKBaseError.new(:status_code => 500, :error_message => "", :errors_object => Errors)
|
10
|
+
# SDKBaseError.new(:status_code => 404, :error_message => "Not Found")
|
11
|
+
def initialize(arg = nil)
|
12
|
+
if arg.is_a? Hash
|
13
|
+
arg.each do |k, v|
|
14
|
+
if k.to_s == 'error_message'
|
15
|
+
@error_message = v
|
16
|
+
super v
|
17
|
+
else
|
18
|
+
instance_variable_set "@#{k}", v
|
19
|
+
end
|
20
|
+
end
|
21
|
+
else
|
22
|
+
super arg
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative '../exceptions/sdk_base_error'
|
2
|
+
|
3
|
+
module MastercardCoreSdk
|
4
|
+
module Exceptions
|
5
|
+
# Defines error to be raised on conversion failure.
|
6
|
+
class SDKConversionError < SDKBaseError
|
7
|
+
|
8
|
+
attr_accessor :error_message, :source
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
@error_message = args[:error_message]
|
12
|
+
@source = args[:source]
|
13
|
+
super(args[:error_message])
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative '../exceptions/sdk_base_error'
|
2
|
+
|
3
|
+
module MastercardCoreSdk
|
4
|
+
module Exceptions
|
5
|
+
# Defines error to be raised for OAuth calls.
|
6
|
+
class SDKOAuthError < SDKBaseError
|
7
|
+
attr_accessor :error_message
|
8
|
+
|
9
|
+
def initialize(error_message)
|
10
|
+
@error_message = error_message
|
11
|
+
super(error_message)
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../exceptions/sdk_base_error'
|
2
|
+
|
3
|
+
module MastercardCoreSdk
|
4
|
+
module Exceptions
|
5
|
+
# Defines error to be raised with details in error object.
|
6
|
+
class SDKResponseError < SDKBaseError
|
7
|
+
|
8
|
+
attr_accessor :errors_object, :status_code
|
9
|
+
|
10
|
+
def initialize(args)
|
11
|
+
@errors_object = args[:errors_object]
|
12
|
+
@status_code = args[:status_code]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|