|
1
|
|
|
''' |
|
2
|
|
|
Created on Nov 1, 2015 |
|
3
|
|
|
|
|
4
|
|
|
@author: krgupta |
|
5
|
|
|
''' |
|
6
|
|
|
import abc |
|
7
|
|
|
import logging |
|
8
|
|
|
import xml.dom.minidom |
|
9
|
|
|
from pip._vendor import requests |
|
10
|
|
|
from _pyio import __metaclass__ |
|
11
|
|
|
|
|
12
|
|
|
from authorizenet.constants import constants |
|
13
|
|
|
from authorizenet import apicontractsv1 |
|
14
|
|
|
from authorizenet import utility |
|
15
|
|
|
''' |
|
16
|
|
|
from authorizenet.apicontractsv1 import merchantAuthenticationType |
|
17
|
|
|
from authorizenet.apicontractsv1 import ANetApiRequest |
|
18
|
|
|
from authorizenet.apicontractsv1 import ANetApiResponse |
|
19
|
|
|
''' |
|
20
|
|
|
class APIOperationBaseInterface(object): |
|
21
|
|
|
|
|
22
|
|
|
__metaclass__ = abc.ABCMeta |
|
23
|
|
|
|
|
24
|
|
|
@abc.abstractmethod |
|
25
|
|
|
def execute(self): |
|
26
|
|
|
''' |
|
27
|
|
|
Makes a http-post call. |
|
28
|
|
|
Uses request xml and response class type to check that the response was of correct type |
|
29
|
|
|
''' |
|
30
|
|
|
pass |
|
31
|
|
|
|
|
32
|
|
|
@abc.abstractmethod |
|
33
|
|
|
def getresponseclass(self): |
|
34
|
|
|
''' Returns the response class ''' |
|
35
|
|
|
pass |
|
36
|
|
|
|
|
37
|
|
|
@abc.abstractmethod |
|
38
|
|
|
def getrequesttype(self): |
|
39
|
|
|
''' Returns the request class ''' |
|
40
|
|
|
pass |
|
41
|
|
|
|
|
42
|
|
|
@abc.abstractmethod |
|
43
|
|
|
def getresponse(self): |
|
44
|
|
|
''' Returns the de-serialized response''' |
|
45
|
|
|
pass |
|
46
|
|
|
|
|
47
|
|
|
@abc.abstractmethod |
|
48
|
|
|
def getresultcode(self): |
|
49
|
|
|
''' Returns the result code from the response ''' |
|
50
|
|
|
pass |
|
51
|
|
|
|
|
52
|
|
|
@abc.abstractmethod |
|
53
|
|
|
def getmessagetype(self): |
|
54
|
|
|
''' Returns the message type enum from the response ''' |
|
55
|
|
|
pass |
|
56
|
|
|
|
|
57
|
|
|
@abc.abstractmethod |
|
58
|
|
|
def afterexecute(self): |
|
59
|
|
|
'''Returns the message received from binding after processing request''' |
|
60
|
|
|
pass |
|
61
|
|
|
|
|
62
|
|
|
@abc.abstractmethod |
|
63
|
|
|
def beforeexecute(self): |
|
64
|
|
|
'''TODO''' |
|
65
|
|
|
pass |
|
66
|
|
|
|
|
67
|
|
|
class APIOperationBase(APIOperationBaseInterface): |
|
68
|
|
|
__metaclass__ = abc.ABCMeta |
|
69
|
|
|
|
|
70
|
|
|
__initialized = False |
|
71
|
|
|
__merchantauthentication = "null" |
|
72
|
|
|
__environment = "null" |
|
73
|
|
|
|
|
74
|
|
|
@staticmethod |
|
75
|
|
|
def __classinitialized(): |
|
76
|
|
|
return APIOperationBase.__initialized |
|
77
|
|
|
|
|
78
|
|
|
@abc.abstractmethod |
|
79
|
|
|
def validaterequest(self): |
|
80
|
|
|
return |
|
81
|
|
|
|
|
82
|
|
|
def validate(self): |
|
83
|
|
|
anetapirequest = self._getrequest() |
|
84
|
|
|
self.validateandsetmerchantauthentication() |
|
85
|
|
|
self.validaterequest() |
|
86
|
|
|
|
|
87
|
|
|
return |
|
88
|
|
|
|
|
89
|
|
|
def _getrequest(self): #protected method |
|
90
|
|
|
return self._request |
|
91
|
|
|
|
|
92
|
|
|
def buildrequest(self): |
|
93
|
|
|
logging.debug('building request..') |
|
94
|
|
|
|
|
95
|
|
|
xmlRequest = self._request.toxml(encoding=constants.xml_encoding, element_name=self.getrequesttype()) |
|
96
|
|
|
#remove namespaces that toxml() generates |
|
97
|
|
|
xmlRequest = xmlRequest.replace(constants.nsNamespace1, '') |
|
98
|
|
|
xmlRequest = xmlRequest.replace(constants.nsNamespace2, '') |
|
99
|
|
|
|
|
100
|
|
|
return xmlRequest |
|
101
|
|
|
|
|
102
|
|
|
def getprettyxmlrequest(self): |
|
103
|
|
|
xmlRequest = self.buildrequest() |
|
104
|
|
|
requestDom = xml.dom.minidom.parseString(xmlRequest) |
|
105
|
|
|
logging.debug('Request is: %s' % requestDom.toprettyxml()) |
|
106
|
|
|
|
|
107
|
|
|
return requestDom |
|
108
|
|
|
|
|
109
|
|
|
def execute(self): |
|
110
|
|
|
|
|
111
|
|
|
self.endpoint = APIOperationBase.__environment |
|
112
|
|
|
|
|
113
|
|
|
logging.debug('Executing http post to url: %s', self.endpoint) |
|
114
|
|
|
|
|
115
|
|
|
self.beforeexecute() |
|
116
|
|
|
|
|
117
|
|
|
proxyDictionary = {'http' : utility.helper.getproperty("http"), |
|
118
|
|
|
'https' : utility.helper.getproperty("https"), |
|
119
|
|
|
'ftp' : utility.helper.getproperty("ftp")} |
|
120
|
|
|
|
|
121
|
|
|
#requests is http request |
|
122
|
|
|
|
|
123
|
|
|
try: |
|
124
|
|
|
xmlRequest = self.buildrequest() |
|
125
|
|
|
self._httpResponse = requests.post(self.endpoint, data=xmlRequest, headers=constants.headers, proxies=proxyDictionary) |
|
126
|
|
|
except Exception as httpException: |
|
127
|
|
|
logging.error( 'Error retrieving http response from: %s for request: %s', self.endpoint, self.getprettyxmlrequest()) |
|
128
|
|
|
logging.error( 'Exception: %s, %s', type(httpException), httpException.args ) |
|
129
|
|
|
|
|
130
|
|
|
|
|
131
|
|
|
if self._httpResponse: |
|
132
|
|
|
#encoding of response should be changed to retrieve text of response |
|
133
|
|
|
self._httpResponse.encoding = constants.response_encoding |
|
134
|
|
|
self._httpResponse = self._httpResponse.text[3:] #strip BOM |
|
135
|
|
|
self.afterexecute() |
|
136
|
|
|
try: |
|
137
|
|
|
self._response = apicontractsv1.CreateFromDocument(self._httpResponse) |
|
138
|
|
|
except Exception as createfromdocumentexception: |
|
139
|
|
|
logging.error( 'Create Document Exception: %s, %s', type(createfromdocumentexception), createfromdocumentexception.args ) |
|
140
|
|
|
else: |
|
141
|
|
|
if type(self.getresponseclass()) == type(self._response): |
|
142
|
|
|
if self._response.messages.resultCode == "Error": |
|
143
|
|
|
print "Response error" |
|
144
|
|
|
|
|
145
|
|
|
domResponse = xml.dom.minidom.parseString(self._httpResponse) |
|
146
|
|
|
logging.debug('Received response: %s' % domResponse.toprettyxml()) |
|
147
|
|
|
else: |
|
148
|
|
|
#Need to handle ErrorResponse |
|
149
|
|
|
logging.debug('Error retrieving response for request: %s' % self._request) |
|
150
|
|
|
else: |
|
151
|
|
|
print "Did not receive http response" |
|
152
|
|
|
return |
|
153
|
|
|
|
|
154
|
|
|
def getresponse(self): |
|
155
|
|
|
return self._response |
|
156
|
|
|
|
|
157
|
|
|
def getresultcode(self): |
|
158
|
|
|
resultcode = 'null' |
|
159
|
|
|
if self._response: |
|
160
|
|
|
resultcode = self._response.resultCode |
|
161
|
|
|
return resultcode |
|
162
|
|
|
|
|
163
|
|
|
def getmessagetype(self): |
|
164
|
|
|
message = 'null' |
|
165
|
|
|
if self._response: |
|
166
|
|
|
message = self._response.message |
|
167
|
|
|
return message |
|
168
|
|
|
|
|
169
|
|
|
def afterexecute(self ): |
|
170
|
|
|
return |
|
171
|
|
|
|
|
172
|
|
|
def beforeexecute(self): |
|
173
|
|
|
return |
|
174
|
|
|
|
|
175
|
|
|
@staticmethod |
|
176
|
|
|
def getmerchantauthentication(self): |
|
177
|
|
|
return self.__merchantauthentication |
|
178
|
|
|
|
|
179
|
|
|
@staticmethod |
|
180
|
|
|
def setmerchantauthentication(merchantauthentication): |
|
181
|
|
|
APIOperationBase.__merchantauthentication = merchantauthentication |
|
182
|
|
|
return |
|
183
|
|
|
|
|
184
|
|
|
def validateandsetmerchantauthentication(self): |
|
185
|
|
|
anetapirequest = apicontractsv1.ANetApiRequest() |
|
186
|
|
|
if (anetapirequest.merchantAuthentication == "null"): |
|
187
|
|
|
if (self.getmerchantauthentication() != "null"): |
|
188
|
|
|
anetapirequest.merchantAuthentication = self.getmerchantauthentication() |
|
189
|
|
|
else: |
|
190
|
|
|
raise ValueError('Merchant Authentication can not be null') |
|
191
|
|
|
return |
|
192
|
|
|
|
|
193
|
|
|
@staticmethod |
|
194
|
|
|
def getenvironment(self): |
|
195
|
|
|
return APIOperationBase.__environment |
|
196
|
|
|
|
|
197
|
|
|
|
|
198
|
|
|
@staticmethod |
|
199
|
|
|
def setenvironment(userenvironment): |
|
200
|
|
|
APIOperationBase.__environment = userenvironment |
|
201
|
|
|
return |
|
202
|
|
|
|
|
203
|
|
|
def __init__(self, apiRequest): |
|
204
|
|
|
self._httpResponse = None |
|
205
|
|
|
self._request = None |
|
206
|
|
|
self._response = None |
|
207
|
|
|
|
|
208
|
|
|
if None == apiRequest: |
|
209
|
|
|
raise ValueError('Input request cannot be null') |
|
210
|
|
|
|
|
211
|
|
|
self._request = apiRequest |
|
212
|
|
|
__merchantauthentication = apicontractsv1.merchantAuthenticationType() |
|
213
|
|
|
APIOperationBase.__environment = constants.SANDBOX_TESTMODE |
|
214
|
|
|
|
|
215
|
|
|
APIOperationBase.setmerchantauthentication(__merchantauthentication) |
|
216
|
|
|
|
|
217
|
|
|
if ( False == APIOperationBase.__classinitialized()): |
|
218
|
|
|
loggingfilename = utility.helper.getproperty(constants.propertiesloggingfilename) |
|
219
|
|
|
logginglevel = utility.helper.getproperty(constants.propertiesexecutionlogginglevel) |
|
220
|
|
|
|
|
221
|
|
|
if (None == loggingfilename): |
|
222
|
|
|
loggingfilename = constants.defaultLogFileName |
|
223
|
|
|
if (None == logginglevel): |
|
224
|
|
|
logginglevel = constants.defaultLoggingLevel |
|
225
|
|
|
|
|
226
|
|
|
logging.basicConfig(filename=loggingfilename, level=logginglevel, format=constants.defaultlogformat) |
|
227
|
|
|
__initialized = True |
|
228
|
|
|
|
|
229
|
|
|
self.validate() |
|
230
|
|
|
|
|
231
|
|
|
return |
|
232
|
|
|
|