Completed
Pull Request — master (#36)
by
unknown
01:28
created

APIOperationBase   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 32
c 3
b 0
f 0
dl 0
loc 167
rs 9.6

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getenvironment() 0 3 1
A afterexecute() 0 2 1
A validaterequest() 0 3 1
A setenvironment() 0 4 1
A buildrequest() 0 9 1
B __init__() 0 29 5
A getresultcode() 0 5 2
C execute() 0 46 7
A beforeexecute() 0 2 1
A validate() 0 6 1
A validateandsetmerchantauthentication() 0 8 3
A getmerchantauthentication() 0 3 1
A setmerchantauthentication() 0 4 1
A getmessagetype() 0 5 2
A _getrequest() 0 2 1
A getresponse() 0 2 1
A getprettyxmlrequest() 0 6 1
A __classinitialized() 0 3 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.GlobalValidationConfig._setForBinding(False)
142
                self._response = apicontractsv1.CreateFromDocument(self._httpResponse)    
143
            else:    
144
                if type(self.getresponseclass()) == type(self._response):
145
                    if self._response.messages.resultCode == "Error":
146
                        print "Response error"
147
            
148
                    domResponse = xml.dom.minidom.parseString(self._httpResponse)
149
                    logging.debug('Received response: %s' % domResponse.toprettyxml())
150
                else:
151
                    #Need to handle ErrorResponse 
152
                    logging.debug('Error retrieving response for request: %s' % self._request)
153
        else:
154
            print "Did not receive http response"
155
        return
156
    
157
    def getresponse(self):
158
        return self._response
159
    
160
    def getresultcode(self):
161
        resultcode = 'null'
162
        if self._response:
163
            resultcode = self._response.resultCode
164
        return resultcode
165
    
166
    def getmessagetype(self):
167
        message = 'null'
168
        if self._response:
169
            message = self._response.message
170
        return message
171
    
172
    def afterexecute(self ):
173
        return 
174
    
175
    def beforeexecute(self):
176
        return 
177
    
178
    @staticmethod
179
    def getmerchantauthentication(self):
180
        return self.__merchantauthentication
181
    
182
    @staticmethod
183
    def setmerchantauthentication(merchantauthentication):
184
        APIOperationBase.__merchantauthentication = merchantauthentication
185
        return
186
    
187
    def validateandsetmerchantauthentication(self):
188
        anetapirequest = apicontractsv1.ANetApiRequest()
189
        if (anetapirequest.merchantAuthentication == "null"):
190
            if (self.getmerchantauthentication() != "null"):
191
                anetapirequest.merchantAuthentication = self.getmerchantauthentication()
192
            else:
193
                raise ValueError('Merchant Authentication can not be null')
194
        return
195
    
196
    @staticmethod
197
    def getenvironment(self):
198
        return APIOperationBase.__environment
199
        
200
    
201
    @staticmethod
202
    def setenvironment(userenvironment):
203
        APIOperationBase.__environment = userenvironment 
204
        return 
205
    
206
    def __init__(self, apiRequest):
207
        self._httpResponse = None
208
        self._request = None
209
        self._response = None
210
               
211
        if None == apiRequest:
212
            raise ValueError('Input request cannot be null')
213
         
214
        self._request = apiRequest
215
        __merchantauthentication = apicontractsv1.merchantAuthenticationType()
216
        APIOperationBase.__environment = constants.SANDBOX
217
        
218
        APIOperationBase.setmerchantauthentication(__merchantauthentication)
219
220
        if ( False == APIOperationBase.__classinitialized()):
221
            loggingfilename = utility.helper.getproperty(constants.propertiesloggingfilename)
222
            logginglevel = utility.helper.getproperty(constants.propertiesexecutionlogginglevel)
223
            
224
            if (None == loggingfilename):
225
                loggingfilename = constants.defaultLogFileName
226
            if (None == logginglevel):
227
                logginglevel = constants.defaultLoggingLevel
228
                
229
            logging.basicConfig(filename=loggingfilename, level=logginglevel, format=constants.defaultlogformat)
230
            __initialized = True
231
232
        self.validate()
233
            
234
        return
235