Completed
Push — master ( 4f59bf...f4be26 )
by Authorize.Net
8s
created

APIOperationBase.getprettyxmlrequest()   A

Complexity

Conditions 1

Size

Total Lines 6

Duplication

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