mastercard_api_core 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 11df59f25e79aa759a551ecfc4aa6e1425b9cd88
4
+ data.tar.gz: 3eef3a4fc2104ddbce60f346e75f905571d7c9a7
5
+ SHA512:
6
+ metadata.gz: 1d11fde3322e775985c14aa7bb7c98a9e5124b8d9471e41cd032f60c8da2105999c3b7519a09317d16150d9a7bd07ad74358222585b1fa0e0f4fb4cd7302a2c9
7
+ data.tar.gz: c198b9395316e85b110661ff1fb82e091fefb8414189dae3911e1ecbcc4973fd5aa51c2d852a4dc78ad2d05bbe488e433e4f51b59a7b411619d9a9f62e013666
@@ -0,0 +1,84 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ require "mastercard/core/constants"
28
+
29
+ module MasterCard
30
+ module Core
31
+ class Config
32
+
33
+ private
34
+ @@sandbox = true
35
+ @@debug = false
36
+ @@authentication = nil
37
+ @@localhost = false
38
+
39
+ public
40
+ def self.setDebug(debug)
41
+ @@debug = debug
42
+ end
43
+
44
+ def self.isDebug()
45
+ return @@debug
46
+ end
47
+
48
+ def self.setSandbox(sandbox)
49
+ @@sandbox = sandbox
50
+ end
51
+
52
+ def self.isSandbox()
53
+ return @@sandbox
54
+ end
55
+
56
+ def self.setLocal(local)
57
+ @@localhost = local
58
+ end
59
+
60
+ def self.isLocal
61
+ return @@localhost
62
+ end
63
+
64
+ def self.setAuthentication(auth)
65
+ @@authentication = auth
66
+ end
67
+
68
+ def self.getAuthentication
69
+ return @@authentication
70
+ end
71
+
72
+ def self.getAPIBaseURL
73
+
74
+ if @@localhost
75
+ return Constants::API_BASE_LOCALHOST_URL
76
+ elsif @@sandbox
77
+ return Constants::API_BASE_SANDBOX_URL
78
+ end
79
+
80
+ return Constants::API_BASE_LIVE_URL
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,36 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ module MasterCard
28
+ module Core
29
+ module Constants
30
+ VERSION = "1.0.0"
31
+ API_BASE_LOCALHOST_URL = "http://localhost:8080"
32
+ API_BASE_LIVE_URL = "https://api.mastercard.com"
33
+ API_BASE_SANDBOX_URL = "https://sandbox.api.mastercard.com"
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,325 @@
1
+ #
2
+ # Copyright (c) 2016 MasterCard International Incorporated
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without modification, are
6
+ # permitted provided that the following conditions are met:
7
+ #
8
+ # Redistributions of source code must retain the above copyright notice, this list of
9
+ # conditions and the following disclaimer.
10
+ # Redistributions in binary form must reproduce the above copyright notice, this list of
11
+ # conditions and the following disclaimer in the documentation and/or other materials
12
+ # provided with the distribution.
13
+ # Neither the name of the MasterCard International Incorporated nor the names of its
14
+ # contributors may be used to endorse or promote products derived from this software
15
+ # without specific prior written permission.
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17
+ # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
+ # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19
+ # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20
+ # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
21
+ # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22
+ # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
+ # SUCH DAMAGE.
26
+ #
27
+ require 'mastercard/core/config'
28
+ require 'mastercard/core/exceptions'
29
+ require 'mastercard/core/util'
30
+ require 'mastercard/security/authentication'
31
+ require 'net/http'
32
+ require 'json'
33
+
34
+ module MasterCard
35
+ module Core
36
+ module Controller
37
+ class APIController
38
+ include MasterCard::Core
39
+ include MasterCard::Core::Exceptions
40
+ include MasterCard::Security
41
+
42
+ ACTION_CREATE = "CREATE"
43
+ ACTION_DELETE = "DELETE"
44
+ ACTION_UPDATE = "UPDATE"
45
+ ACTION_READ = "READ"
46
+ ACTION_LIST = "LIST"
47
+ ACTION_QUERY = "QUERY"
48
+
49
+ KEY_ID = "id"
50
+ KEY_FORMAT = "Format"
51
+ KEY_ACCEPT = "Accept"
52
+ KEY_USER_AGENT = "User-Agent"
53
+ KEY_CONTENT_TYPE = "Content-Type"
54
+ APPLICATION_JSON = "application/json"
55
+ RUBY_SDK = "Ruby_SDK"
56
+ JSON_STR = "JSON"
57
+
58
+
59
+ def initialize(version=nil)
60
+ #Set the parameters
61
+ @baseURL = Config.getAPIBaseURL()
62
+
63
+ @baseURL = removeForwardSlashFromTail(@baseURL)
64
+
65
+ #Verify if the URL is correct
66
+ unless Util.validateURL(@baseURL)
67
+ raise APIException.new "URL: '" + @baseURL + "' is not a valid url"
68
+ end
69
+
70
+ #Set the version
71
+ unless version.nil?
72
+ @version = version
73
+ else
74
+ @version = Constants::VERSION
75
+ end
76
+
77
+ end
78
+
79
+ def execute(action,resourcePath,headerKey,queryKey,input)
80
+
81
+ #Check preconditions for execute
82
+ preCheck()
83
+
84
+ #Separate the headers from the inputMap
85
+ headers = Util.subMap(input,headerKey)
86
+
87
+ #Separate the query from the inputMap
88
+ queryParams = Util.subMap(input,queryKey)
89
+
90
+ #Get the resourcePath containing values from input
91
+ resourcePath = getFullResourcePath(action,resourcePath,input)
92
+
93
+ #Get the path parameters
94
+ pathParams = getPathParams(action,queryParams,input)
95
+ #Get the body
96
+ body = getBody(action,input)
97
+
98
+ #Get the request Object
99
+ request = getRequestObject(resourcePath,action,pathParams,body)
100
+
101
+ #Add headers to request
102
+ headers.each do |key,value|
103
+ request.add_field(key,value)
104
+ end
105
+
106
+ fullUrl = @baseURL+resourcePath
107
+ #Sign and get back the request
108
+ request = Config.getAuthentication().signRequest(fullUrl,request,request.method,body,pathParams)
109
+
110
+ uri = URI.parse(@baseURL)
111
+ #Get the http object
112
+ http = getHTTPObject(uri)
113
+
114
+ if Config.isDebug
115
+ puts "---- Request ----"
116
+ puts ""
117
+ puts "URL"
118
+ puts @baseURL+request.path
119
+ puts ""
120
+ puts "Headers"
121
+ request.each_header do |header_name, header_value|
122
+ puts "#{header_name} : #{header_value}"
123
+ end
124
+ puts ""
125
+ puts "Body"
126
+ puts request.body
127
+ end
128
+
129
+ begin
130
+ response = http.request(request)
131
+
132
+ if Config.isDebug
133
+ puts "---- Response ----"
134
+ puts ""
135
+ puts "Status Code"
136
+ puts response.code
137
+ puts ""
138
+ puts "Headers"
139
+ response.each_header do |header_name, header_value|
140
+ puts "#{header_name} : #{header_value}"
141
+ end
142
+ puts ""
143
+ puts "Body"
144
+ puts response.body
145
+ end
146
+
147
+
148
+ return handleResponse(response,response.body)
149
+ rescue Errno::ECONNREFUSED
150
+ raise APIException.new ("Connection to server could not be established.")
151
+ end
152
+
153
+
154
+ end
155
+
156
+
157
+ private
158
+
159
+
160
+ def handleResponse(response,content)
161
+ #Handles the exception and response
162
+ status = response.code.to_i
163
+
164
+ if content
165
+ begin
166
+ content = JSON.load content
167
+ rescue JSON::ParserError
168
+ end
169
+ end
170
+
171
+ if 200 <= status && status <= 299
172
+ return content
173
+ elsif 300 <= status && status <= 399
174
+ raise InvalidRequestException.new("Unexpected response code returned from the API causing redirect",status,content)
175
+ elsif status == 400
176
+ raise InvalidRequestException.new("Bad request",status,content)
177
+ elsif status == 401
178
+ raise APIException.new("You are not authorized to make this request",status,content)
179
+ elsif status == 403
180
+ raise APIException.new("You are not authorized to make this request",status,content)
181
+ elsif status == 404
182
+ raise ObjectNotFoundException.new("Object not found",status,content)
183
+ elsif status == 405
184
+ raise APIException.new("Operation not allowed",status,content)
185
+ else
186
+ raise SystemException.new("Internal Server Error",status,content)
187
+ end
188
+
189
+ end
190
+
191
+ def getBody(action,input)
192
+ #Returns the body hash depending on action
193
+ body = nil
194
+ case action.upcase
195
+ when ACTION_CREATE, ACTION_UPDATE
196
+ unless input.nil?
197
+ body = input
198
+ end
199
+ end
200
+ return body
201
+ end
202
+
203
+ def getPathParams(action,queryParams,input)
204
+ #Returns the path params based on action
205
+ pathParams = {KEY_FORMAT => JSON_STR}
206
+ case action.upcase
207
+ when ACTION_LIST, ACTION_READ, ACTION_QUERY, ACTION_DELETE
208
+ unless input.nil?
209
+ pathParams = pathParams.merge(input)
210
+ end
211
+ end
212
+
213
+ #merge the queryParams
214
+ pathParams = pathParams.merge(queryParams)
215
+
216
+ return pathParams
217
+ end
218
+
219
+ def getHTTPObject(uri)
220
+ #Returns the HTTP Object
221
+ http = Net::HTTP.new(uri.host,uri.port)
222
+
223
+ unless Config.isLocal()
224
+ http.use_ssl = true
225
+ end
226
+
227
+ return http
228
+
229
+ end
230
+
231
+ def encode_path_params(path, params)
232
+ #Encode and join the params
233
+ encoded = URI.encode_www_form(params)
234
+ [path, encoded].join("?")
235
+ end
236
+
237
+ def getRequestObject(path,action,pathParams,body)
238
+ #Retuns the request object based on action
239
+ case action.upcase
240
+ when ACTION_LIST, ACTION_READ, ACTION_QUERY
241
+ verb = Net::HTTP::Get
242
+
243
+ when ACTION_CREATE
244
+ verb = Net::HTTP::Post
245
+
246
+ when ACTION_DELETE
247
+ verb = Net::HTTP::Delete
248
+
249
+ when ACTION_UPDATE
250
+ verb = Net::HTTP::Put
251
+ else
252
+ raise APIException.new "Invalid action #{action}"
253
+ end
254
+
255
+ #add url parameters to path
256
+ path = encode_path_params(path,pathParams)
257
+
258
+ req = verb.new(path)
259
+
260
+ #Add default headers
261
+ req.add_field(KEY_ACCEPT,APPLICATION_JSON)
262
+ req.add_field(KEY_CONTENT_TYPE,APPLICATION_JSON)
263
+ req.add_field(KEY_USER_AGENT,RUBY_SDK+"/"+@version)
264
+
265
+ #Add body
266
+
267
+ unless body.nil?
268
+ req.body = body.to_json
269
+ end
270
+
271
+ return req
272
+
273
+
274
+ end
275
+
276
+ def preCheck()
277
+ #check if execute can be done
278
+ auth = Config.getAuthentication()
279
+
280
+ unless (auth.nil? || auth.is_a?(Authentication))
281
+ raise APIException.new "No or incorrect authentication has been configured"
282
+ end
283
+
284
+ end
285
+
286
+ def removeForwardSlashFromTail(text)
287
+ #
288
+ #Removes the trailing / from url if any and returns the url
289
+
290
+ if text.end_with? "/"
291
+ return text[0...-1]
292
+ end
293
+
294
+ return text
295
+
296
+ end
297
+
298
+ def getFullResourcePath(action,resourcePath,inputMap)
299
+ #
300
+ #Forms the complete URL by combining baseURL and replaced path variables in resourcePath from inputMap
301
+
302
+
303
+ #Remove the Trailing slash from the resource path
304
+ resourcePath = removeForwardSlashFromTail(resourcePath)
305
+
306
+ #Replace the path variables
307
+ resourcePath = Util.getReplacedPath(resourcePath,inputMap)
308
+
309
+ #This step is if id is in inputMap but was not specified in URL as /{id}
310
+ #If the action is read,update or delete we add this id
311
+ if inputMap.has_key?(KEY_ID)
312
+ if [ACTION_READ,ACTION_UPDATE,ACTION_DELETE].include? action.upcase
313
+ resourcePath += "/"+inputMap[KEY_ID].to_s
314
+ inputMap.delete(KEY_ID) #Remove from input path otherwise this would get add in query params as well
315
+ end
316
+ end
317
+
318
+ return resourcePath
319
+
320
+ end
321
+
322
+ end
323
+ end
324
+ end
325
+ end