• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/opal/ZSI/build/lib/ZSI/address.py

00001 ############################################################################
00002 # Joshua R. Boverhof, LBNL
00003 # See Copyright for copyright notice!
00004 ###########################################################################
00005 
00006 import time, urlparse, socket
00007 from ZSI import _seqtypes, EvaluateException, WSActionException
00008 from TC import AnyElement, AnyType, TypeCode
00009 from schema import GED, GTD, _has_type_definition
00010 from ZSI.TCcompound import ComplexType
00011 from ZSI.wstools.Namespaces import WSA_LIST
00012 
00013 
00014 class Address(object):
00015     '''WS-Address
00016 
00017     Implemented is dependent on the default "wsdl2py" convention of generating aname,
00018     so the attributes representing element declaration names should be prefixed with
00019     an underscore.
00020     '''
00021     def __init__(self, addressTo=None, wsAddressURI=None, action=None):
00022         self.wsAddressURI = wsAddressURI
00023         self.anonymousURI = None
00024         self._addressTo = addressTo
00025         self._messageID = None
00026         self._action = action
00027         self._endPointReference = None
00028         self._replyTo = None
00029         self._relatesTo = None
00030         self.setUp()
00031 
00032     def setUp(self):
00033         '''Look for WS-Address
00034         '''
00035         toplist = filter(lambda wsa: wsa.ADDRESS==self.wsAddressURI, WSA_LIST)
00036         epr = 'EndpointReferenceType'
00037         for WSA in toplist+WSA_LIST:
00038             if (self.wsAddressURI is not None and self.wsAddressURI != WSA.ADDRESS) or \
00039                 _has_type_definition(WSA.ADDRESS, epr) is True:
00040                 break
00041         else:
00042             raise EvaluateException,\
00043                 'enabling wsAddressing requires the inclusion of that namespace'
00044 
00045         self.wsAddressURI = WSA.ADDRESS
00046         self.anonymousURI = WSA.ANONYMOUS
00047         self._replyTo = WSA.ANONYMOUS
00048 
00049     def _checkAction(self, action, value):
00050         '''WS-Address Action
00051         action -- Action value expecting.
00052         value  -- Action value server returned.
00053         '''
00054         if action is None:
00055             raise WSActionException, 'Response missing WSAddress Action'
00056         if not value:
00057             raise WSActionException, 'missing WSAddress Action, expecting %s' %action
00058         if value != action:
00059             raise WSActionException, 'wrong WSAddress Action(%s), expecting %s'%(value,action)
00060 
00061     def _checkFrom(self, pyobj):
00062         '''WS-Address From, 
00063         XXX currently not checking the hostname, not forwarding messages.
00064         pyobj  -- From server returned.
00065         '''
00066         if pyobj is None: return
00067         value = pyobj._Address
00068         if value != self._addressTo:
00069             scheme,netloc,path,query,fragment = urlparse.urlsplit(value)
00070             hostport = netloc.split(':')
00071             schemeF,netlocF,pathF,queryF,fragmentF = urlparse.urlsplit(self._addressTo)
00072             if scheme==schemeF and path==pathF and query==queryF and fragment==fragmentF:
00073                 netloc = netloc.split(':') + ['80']
00074                 netlocF = netlocF.split(':') + ['80']
00075                 if netloc[1]==netlocF[1] and (socket.gethostbyname(netlocF[0]) in
00076                     ('127.0.0.1', socket.gethostbyname(netloc[0]))):
00077                     return
00078 
00079             raise WSActionException, 'wrong WS-Address From(%s), expecting %s'%(value,self._addressTo)
00080 
00081     def _checkRelatesTo(self, value):
00082         '''WS-Address From
00083         value  -- From server returned.
00084         '''
00085         if value != self._messageID:
00086             raise WSActionException, 'wrong WS-Address RelatesTo(%s), expecting %s'%(value,self._messageID)
00087         
00088     def _checkReplyTo(self, value):
00089         '''WS-Address From
00090         value  -- From server returned in wsa:To
00091         '''
00092         if value != self._replyTo:
00093             raise WSActionException, 'wrong WS-Address ReplyTo(%s), expecting %s'%(value,self._replyTo)
00094 
00095     def setAction(self, action):
00096         self._action = action
00097 
00098     def getAction(self):
00099         return self._action
00100 
00101     def getRelatesTo(self):
00102         return self._relatesTo
00103 
00104     def getMessageID(self):
00105         return self._messageID
00106 
00107     def _getWSAddressTypeCodes(self, **kw):
00108         '''kw -- namespaceURI keys with sequence of element names.
00109         '''
00110         typecodes = []
00111         try:
00112             for nsuri,elements in kw.items():
00113                 for el in elements:
00114                     typecode = GED(nsuri, el)
00115                     if typecode is None:
00116                         raise WSActionException, 'Missing namespace, import "%s"' %nsuri
00117 
00118                     typecodes.append(typecode)
00119             else:
00120                 pass
00121         except EvaluateException, ex:
00122             raise EvaluateException, \
00123                 'To use ws-addressing register typecodes for namespace(%s)' %self.wsAddressURI
00124         return typecodes
00125 
00126     def checkResponse(self, ps, action):
00127         ''' 
00128         ps -- ParsedSoap
00129         action -- ws-action for response
00130         '''
00131         namespaceURI = self.wsAddressURI
00132         d = {namespaceURI:("MessageID","Action","To","From","RelatesTo")}
00133         typecodes = self._getWSAddressTypeCodes(**d)
00134         pyobjs = ps.ParseHeaderElements(typecodes)
00135 
00136         got_action = pyobjs.get((namespaceURI,"Action"))
00137         self._checkAction(action, got_action)
00138 
00139         From = pyobjs.get((namespaceURI,"From"))
00140         self._checkFrom(From)
00141 
00142         RelatesTo = pyobjs.get((namespaceURI,"RelatesTo"))
00143         self._checkRelatesTo(RelatesTo)
00144 
00145         To = pyobjs.get((namespaceURI,"To"))
00146         if To: self._checkReplyTo(To)
00147 
00148     def setRequest(self, endPointReference, action):
00149         '''Call For Request
00150         '''
00151         self._action = action
00152         self.header_pyobjs = None
00153         pyobjs = []
00154         namespaceURI = self.wsAddressURI
00155         addressTo = self._addressTo
00156         messageID = self._messageID = "uuid:%s" %time.time()
00157 
00158         # Set Message Information Headers
00159         # MessageID
00160         typecode = GED(namespaceURI, "MessageID")
00161         pyobjs.append(typecode.pyclass(messageID))
00162 
00163         # Action
00164         typecode = GED(namespaceURI, "Action")
00165         pyobjs.append(typecode.pyclass(action))
00166 
00167         # To
00168         typecode = GED(namespaceURI, "To")
00169         pyobjs.append(typecode.pyclass(addressTo))
00170 
00171         # From
00172         typecode = GED(namespaceURI, "From")
00173         mihFrom = typecode.pyclass()
00174         mihFrom._Address = self.anonymousURI
00175         pyobjs.append(mihFrom)
00176 
00177         if endPointReference:
00178             if hasattr(endPointReference, 'typecode') is False:
00179                 raise EvaluateException, 'endPointReference must have a typecode attribute'
00180 
00181             if isinstance(endPointReference.typecode, \
00182                 GTD(namespaceURI ,'EndpointReferenceType')) is False:
00183                 raise EvaluateException, 'endPointReference must be of type %s' \
00184                     %GTD(namespaceURI ,'EndpointReferenceType')
00185 
00186             ReferenceProperties = getattr(endPointReference, '_ReferenceProperties', None)
00187             if ReferenceProperties is not None:
00188                 for v in getattr(ReferenceProperties, '_any', ()):
00189                     if not hasattr(v,'typecode'):
00190                        raise EvaluateException, '<any> element, instance missing typecode attribute'
00191 
00192                     pyobjs.append(v)
00193 
00194         self.header_pyobjs = tuple(pyobjs)
00195 
00196     def setResponseFromWSAddress(self, address, localURL):
00197         '''Server-side has to set these fields in response.
00198         address -- Address instance, representing a WS-Address
00199         '''
00200         self.From = localURL
00201         self.header_pyobjs = None
00202         pyobjs = []
00203         namespaceURI = self.wsAddressURI
00204 
00205         for nsuri,name,value in (\
00206              (namespaceURI, "Action", self._action), 
00207              (namespaceURI, "MessageID","uuid:%s" %time.time()),
00208              (namespaceURI, "RelatesTo", address.getMessageID()),
00209              (namespaceURI, "To", self.anonymousURI),):
00210 
00211             typecode = GED(nsuri, name)
00212             pyobjs.append(typecode.pyclass(value))
00213 
00214         typecode = GED(nsuri, "From")
00215         pyobj = typecode.pyclass()
00216         pyobj._Address = self.From
00217         pyobjs.append(pyobj)
00218         self.header_pyobjs = tuple(pyobjs)
00219 
00220 
00221     def serialize(self, sw, **kw):
00222         '''
00223         sw -- SoapWriter instance, add WS-Address header.
00224         '''
00225         for pyobj in self.header_pyobjs:
00226             if hasattr(pyobj, 'typecode') is False:
00227                 raise RuntimeError, 'all header pyobjs must have a typecode attribute'
00228 
00229             sw.serialize_header(pyobj, **kw)
00230         
00231 
00232     def parse(self, ps, **kw):
00233         '''
00234         ps -- ParsedSoap instance
00235         '''
00236         namespaceURI = self.wsAddressURI
00237         elements = ("MessageID","Action","To","From","RelatesTo")
00238         d = {namespaceURI:elements}
00239         typecodes = self._getWSAddressTypeCodes(**d)
00240         pyobjs = ps.ParseHeaderElements(typecodes)
00241         self._messageID = pyobjs[(namespaceURI,elements[0])]
00242         self._action = pyobjs[(namespaceURI,elements[1])]
00243         self._addressTo = pyobjs[(namespaceURI,elements[2])]
00244         self._from = pyobjs[(namespaceURI,elements[3])]
00245         self._relatesTo = pyobjs[(namespaceURI,elements[4])]
00246 
00247 
00248 
00249 if __name__ == '__main__': print _copyright

Generated on Wed Oct 20 2010 11:12:15 for APBS by  doxygen 1.7.2