00001
00002
00003 '''Faults.
00004 '''
00005
00006 from ZSI import _copyright, _children, _child_elements, \
00007 _get_idstr, _stringtypes, _seqtypes, _Node, SoapWriter, ZSIException
00008
00009 from ZSI.TCcompound import Struct
00010 from ZSI.TC import QName, URI, String, XMLString, AnyElement, UNBOUNDED
00011
00012 from ZSI.wstools.Namespaces import SOAP, ZSI_SCHEMA_URI
00013 from ZSI.wstools.c14n import Canonicalize
00014 from ZSI.TC import ElementDeclaration
00015
00016 import traceback, cStringIO as StringIO
00017
00018
00019 class Detail:
00020 def __init__(self, any=None):
00021 self.any = any
00022
00023 Detail.typecode = Struct(Detail, [AnyElement(aname='any',minOccurs=0, maxOccurs="unbounded",processContents="lax")], pname='detail', minOccurs=0)
00024
00025 class FaultType:
00026 def __init__(self, faultcode=None, faultstring=None, faultactor=None, detail=None):
00027 self.faultcode = faultcode
00028 self.faultstring= faultstring
00029 self.faultactor = faultactor
00030 self.detail = detail
00031
00032 FaultType.typecode = \
00033 Struct(FaultType,
00034 [QName(pname='faultcode'),
00035 String(pname='faultstring'),
00036 URI(pname=(SOAP.ENV,'faultactor'), minOccurs=0),
00037 Detail.typecode,
00038 AnyElement(aname='any',minOccurs=0, maxOccurs=UNBOUNDED, processContents="lax"),
00039 ],
00040 pname=(SOAP.ENV,'Fault'),
00041 inline=True,
00042 hasextras=0,
00043 )
00044
00045 class ZSIHeaderDetail:
00046 def __init__(self, detail):
00047 self.any = detail
00048
00049 ZSIHeaderDetail.typecode =\
00050 Struct(ZSIHeaderDetail,
00051 [AnyElement(aname='any', minOccurs=0, maxOccurs=UNBOUNDED, processContents="lax")],
00052 pname=(ZSI_SCHEMA_URI, 'detail'))
00053
00054
00055 class ZSIFaultDetailTypeCode(ElementDeclaration, Struct):
00056 '''<ZSI:FaultDetail>
00057 <ZSI:string>%s</ZSI:string>
00058 <ZSI:trace>%s</ZSI:trace>
00059 </ZSI:FaultDetail>
00060 '''
00061 schema = ZSI_SCHEMA_URI
00062 literal = 'FaultDetail'
00063 def __init__(self, **kw):
00064 Struct.__init__(self, ZSIFaultDetail, [String(pname=(ZSI_SCHEMA_URI, 'string')),
00065 String(pname=(ZSI_SCHEMA_URI, 'trace'),minOccurs=0),],
00066 pname=(ZSI_SCHEMA_URI, 'FaultDetail'), **kw
00067 )
00068
00069 class ZSIFaultDetail:
00070 def __init__(self, string=None, trace=None):
00071 self.string = string
00072 self.trace = trace
00073
00074 def __str__(self):
00075 if self.trace:
00076 return self.string + '\n[trace: ' + self.trace + ']'
00077 return self.string
00078
00079 def __repr__(self):
00080 return "<%s.ZSIFaultDetail %s>" % (__name__, _get_idstr(self))
00081 ZSIFaultDetail.typecode = ZSIFaultDetailTypeCode()
00082
00083
00084 class URIFaultDetailTypeCode(ElementDeclaration, Struct):
00085 '''
00086 <ZSI:URIFaultDetail>
00087 <ZSI:URI>uri</ZSI:URI>
00088 <ZSI:localname>localname</ZSI:localname>
00089 </ZSI:URIFaultDetail>
00090 '''
00091 schema = ZSI_SCHEMA_URI
00092 literal = 'URIFaultDetail'
00093 def __init__(self, **kw):
00094 Struct.__init__(self, URIFaultDetail,
00095 [String(pname=(ZSI_SCHEMA_URI, 'URI')), String(pname=(ZSI_SCHEMA_URI, 'localname')),],
00096 pname=(ZSI_SCHEMA_URI, 'URIFaultDetail'), **kw
00097 )
00098
00099 class URIFaultDetail:
00100 def __init__(self, uri=None, localname=None):
00101 self.URI = uri
00102 self.localname = localname
00103 URIFaultDetail.typecode = URIFaultDetailTypeCode()
00104
00105
00106 class ActorFaultDetailTypeCode(ElementDeclaration, Struct):
00107 '''
00108 <ZSI:ActorFaultDetail>
00109 <ZSI:URI>%s</ZSI:URI>
00110 </ZSI:ActorFaultDetail>
00111 '''
00112 schema = ZSI_SCHEMA_URI
00113 literal = 'ActorFaultDetail'
00114 def __init__(self, **kw):
00115 Struct.__init__(self, ActorFaultDetail, [String(pname=(ZSI_SCHEMA_URI, 'URI')),],
00116 pname=(ZSI_SCHEMA_URI, 'ActorFaultDetail'), **kw
00117 )
00118
00119 class ActorFaultDetail:
00120 def __init__(self, uri=None):
00121 self.URI = uri
00122 ActorFaultDetail.typecode = ActorFaultDetailTypeCode()
00123
00124
00125 class Fault(ZSIException):
00126 '''SOAP Faults.
00127 '''
00128
00129 Client = "SOAP-ENV:Client"
00130 Server = "SOAP-ENV:Server"
00131 MU = "SOAP-ENV:MustUnderstand"
00132
00133 def __init__(self, code, string,
00134 actor=None, detail=None, headerdetail=None):
00135 if detail is not None and type(detail) not in _seqtypes:
00136 detail = (detail,)
00137 if headerdetail is not None and type(headerdetail) not in _seqtypes:
00138 headerdetail = (headerdetail,)
00139 self.code, self.string, self.actor, self.detail, self.headerdetail = \
00140 code, string, actor, detail, headerdetail
00141 ZSIException.__init__(self, code, string, actor, detail, headerdetail)
00142
00143 def DataForSOAPHeader(self):
00144 if not self.headerdetail: return None
00145
00146 return ZSIHeaderDetail(self.headerdetail)
00147
00148 def serialize(self, sw):
00149 '''Serialize the object.'''
00150 detail = None
00151 if self.detail is not None:
00152 detail = Detail()
00153 detail.any = self.detail
00154
00155 pyobj = FaultType(self.code, self.string, self.actor, detail)
00156 sw.serialize(pyobj, typed=False)
00157
00158 def AsSOAP(self, **kw):
00159
00160 header = self.DataForSOAPHeader()
00161 sw = SoapWriter(**kw)
00162 self.serialize(sw)
00163 if header is not None:
00164 sw.serialize_header(header, header.typecode, typed=False)
00165 return str(sw)
00166
00167 def __str__(self):
00168 strng = str(self.string) + "\n"
00169 if hasattr(self, 'detail'):
00170 if hasattr(self.detail, '__len__'):
00171 for d in self.detail:
00172 strng += str(d)
00173 else:
00174 strng += str(self.detail)
00175 return strng
00176
00177 def __repr__(self):
00178 return "<%s.Fault at %s>" % (__name__, _get_idstr(self))
00179
00180 AsSoap = AsSOAP
00181
00182
00183 def FaultFromNotUnderstood(uri, localname, actor=None):
00184 detail, headerdetail = None, URIFaultDetail(uri, localname)
00185 return Fault(Fault.MU, 'SOAP mustUnderstand not understood',
00186 actor, detail, headerdetail)
00187
00188
00189 def FaultFromActor(uri, actor=None):
00190 detail, headerdetail = None, ActorFaultDetail(uri)
00191 return Fault(Fault.Client, 'Cannot process specified actor',
00192 actor, detail, headerdetail)
00193
00194
00195 def FaultFromZSIException(ex, actor=None):
00196 '''Return a Fault object created from a ZSI exception object.
00197 '''
00198 mystr = getattr(ex, 'str', None) or str(ex)
00199 mytrace = getattr(ex, 'trace', '')
00200 elt = '''<ZSI:ParseFaultDetail>
00201 <ZSI:string>%s</ZSI:string>
00202 <ZSI:trace>%s</ZSI:trace>
00203 </ZSI:ParseFaultDetail>
00204 ''' % (mystr, mytrace)
00205 if getattr(ex, 'inheader', 0):
00206 detail, headerdetail = None, elt
00207 else:
00208 detail, headerdetail = elt, None
00209 return Fault(Fault.Client, 'Unparseable message',
00210 actor, detail, headerdetail)
00211
00212
00213 def FaultFromException(ex, inheader, tb=None, actor=None):
00214 '''Return a Fault object created from a Python exception.
00215
00216 <SOAP-ENV:Fault>
00217 <faultcode>SOAP-ENV:Server</faultcode>
00218 <faultstring>Processing Failure</faultstring>
00219 <detail>
00220 <ZSI:FaultDetail>
00221 <ZSI:string></ZSI:string>
00222 <ZSI:trace></ZSI:trace>
00223 </ZSI:FaultDetail>
00224 </detail>
00225 </SOAP-ENV:Fault>
00226 '''
00227 tracetext = None
00228 if tb:
00229 try:
00230 lines = '\n'.join(['%s:%d:%s' % (name, line, func)
00231 for name, line, func, text in traceback.extract_tb(tb)])
00232 except:
00233 pass
00234 else:
00235 tracetext = lines
00236
00237 exceptionName = ""
00238 try:
00239 exceptionName = ":".join([ex.__module__, ex.__class__.__name__])
00240 except: pass
00241 elt = ZSIFaultDetail(string=exceptionName + "\n" + str(ex), trace=tracetext)
00242 if inheader:
00243 detail, headerdetail = None, elt
00244 else:
00245 detail, headerdetail = elt, None
00246 return Fault(Fault.Server, 'Processing Failure',
00247 actor, detail, headerdetail)
00248
00249
00250 def FaultFromFaultMessage(ps):
00251 '''Parse the message as a fault.
00252 '''
00253 pyobj = ps.Parse(FaultType.typecode)
00254
00255 if pyobj.detail == None: detailany = None
00256 else: detailany = pyobj.detail.any
00257
00258 return Fault(pyobj.faultcode, pyobj.faultstring,
00259 pyobj.faultactor, detailany)
00260
00261
00262 if __name__ == '__main__': print _copyright