Home | Trees | Indices | Help |
|
---|
|
1 """ 2 Code to expose our services via SOAP and WSDL. 3 """ 4 5 #c Copyright 2008-2019, the GAVO project 6 #c 7 #c This program is free software, covered by the GNU GPL. See the 8 #c COPYING file in the source distribution. 9 10 11 import ZSI 12 from ZSI import TC 13 14 from gavo import base 15 from gavo.base import valuemappers 16 from gavo.utils.stanxml import (Element, schemaURL, registerPrefix) 17 18 19 SOAPNamespace = 'http://schemas.xmlsoap.org/wsdl/soap/' 20 HTTPNamespace = 'http://schemas.xmlsoap.org/wsdl/http/' 21 MIMENamespace = 'http://schemas.xmlsoap.org/wsdl/mime/' 22 WSDLNamespace = 'http://schemas.xmlsoap.org/wsdl/' 23 XSDNamespace = "http://www.w3.org/2001/XMLSchema" 24 25 registerPrefix("soap", SOAPNamespace, 26 schemaURL("wsdlsoap-1.1.xsd")) 27 registerPrefix("http", HTTPNamespace, 28 schemaURL("wsdlhttp-1.1.xsd")) 29 registerPrefix("mime", MIMENamespace, 30 schemaURL("wsdlmime-1.1.xsd")) 31 registerPrefix("wsdl", WSDLNamespace, 32 schemaURL("wsdl-1.1.xsd")) 33 registerPrefix("xsd", XSDNamespace, 34 schemaURL("XMLSchema.xsd")) 35 36 3739 """is a container for elements from the wsdl 1.1 schema. 40 """7342 _prefix = "wsdl"43 47 5153 _additionalPrefixes = frozenset(["xsi"]) 54 _a_name = None 55 _a_targetNamespace = None 56 _a_xmlns_tns = None 57 _name_a_xmlns_tns = "xmlns:tns" 58 _a_xmlns_xsd = XSDNamespace 59 _name_a_xmlns_xsd = "xmlns:xsd"60 6264 _a_name = None65 70 72 _mayBeEmpty = True75 _a_name = None76 80 85 90 9597 _a_name = None98100 _a_name = None101 103 104128 129107 _prefix = "soap"108110 _mayBeEmpty = True 111 _a_style = "rpc" 112 _a_transport = "http://schemas.xmlsoap.org/soap/http"113115 _mayBeEmpty = True 116 _a_use = "encoded" 117 _a_namespace = None 118 _a_encodingStyle = "http://schemas.xmlsoap.org/soap/encoding"119 124131 """is a container for elements from XML schema. 132 """ 136 140 145157 158147 _a_name = None148 150 154156 _a_name = None160 """returns stanxml definitions for the (SOAP) type of service. 161 162 Only "atomic" input parameters are supported so far, so we can 163 skip those. The output type is always called outList and contains 164 of outRec elements. 165 """ 166 return WSDL.types[ 167 XSD.schema(targetNamespace=base.getMetaText(service, "identifier"))[ 168 XSD.element(name="outRec")[ 169 XSD.complexType[ 170 XSD.all[[ 171 XSD.element(name=f.name, type=base.sqltypeToXSD( 172 f.type))[ 173 WSDL.documentation[f.description], 174 WSDL.documentation[f.unit]] 175 for f in service.getCurOutputFields(queryMeta)]]]], 176 XSD.element(name="outList")[ 177 XSD.simpleType[ 178 XSD.list(itemType="outRec")]]]]179 180182 """returns stanxml definitions for the SOAP messages exchanged when 183 using the service. 184 185 Basically, the input message (called srvInput) consists of some 186 combination of the service's input fields, the output message 187 (called srvOutput) is just an outArr. 188 """ 189 return [ 190 WSDL.message(name="srvInput")[[ 191 WSDL.part(name=f.name, type="xsd:"+base.sqltypeToXSD( 192 f.type))[ 193 WSDL.documentation[f.description], 194 WSDL.documentation[f.unit]] 195 for f in service.getInputKeysFor("soap")]], 196 WSDL.message(name="srvOutput")[ 197 WSDL.part(name="srvOutput", type="tns:outList")]]198 199201 """returns stanxml for a port type named serviceSOAP. 202 """ 203 parameterOrder = " ".join([f.name 204 for f in service.getInputKeysFor("soap")]) 205 return WSDL.portType(name="serviceSOAP")[ 206 WSDL.operation(name="useService", parameterOrder=parameterOrder) [ 207 WSDL.input(name="inPars", message="tns:srvInput"), 208 WSDL.output(name="outPars", message="tns:srvOutput"), 209 # XXX TODO: Define fault 210 ]]211 212214 """returns stanxml for a SOAP binding of service. 215 """ 216 tns = base.getMetaText(service, "identifier") 217 return WSDL.binding(name="soapBinding", type="tns:serviceSOAP")[ 218 SOAP.binding, 219 WSDL.operation(name="useService")[ 220 SOAP.operation(soapAction="", name="useService"), 221 WSDL.input(name="inPars")[ 222 SOAP.body(use="encoded", namespace=tns)], 223 WSDL.output(name="inPars")[ 224 SOAP.body(use="encoded", namespace=tns)], 225 ] 226 ]227 228230 """returns stanxml for a WSDL service definition of the SOAP interface 231 to service. 232 """ 233 shortName = base.getMetaText(service, "shortName") 234 return WSDL.service(name=shortName)[ 235 WSDL.port(name="soap_%s"%shortName, binding="tns:soapBinding")[ 236 SOAP.address(location=service.getURL("soap")), 237 ] 238 ]239 240242 """returns an stanxml definitions element describing service. 243 244 The definitions element also introduces a namespace named after the 245 ivoa id of the service, accessible through the tns prefix. 246 """ 247 serviceId = base.getMetaText(service, "identifier") 248 return WSDL.definitions(targetNamespace=serviceId, 249 xmlns_tns=serviceId, 250 name="%s_wsdl"%base.getMetaText(service, "shortName").replace(" ", "_"))[ 251 WSDL.import_, 252 makeTypesForService(service, queryMeta), 253 makeMessagesForService(service), 254 makePortTypeForService(service), 255 makeSOAPBindingForService(service), 256 makeSOAPServiceForService(service), 257 ]258 259261 """is a quick and partial converter from SQL types to ZSI's type codes. 262 """ 263 typeSystem = "ZSITypeCodes" 264 simpleMap = { 265 "smallint": TC.Integer, 266 "integer": TC.Integer, 267 "int": TC.Integer, 268 "bigint": TC.Integer, 269 "real": TC.FPfloat, 270 "float": TC.FPfloat, 271 "boolean": ("boolean", "1"), 272 "double precision": TC.FPdouble, 273 "double": TC.FPdouble, 274 "text": TC.String, 275 "char": TC.String, 276 "date": TC.gDate, 277 "timestamp": TC.gDateTime, 278 "time": TC.gTime, 279 "raw": TC.String, 280 } 281285 286 sqltypeToTC = ToTcConverter().convert 287 288 289 # rather than fooling around with ZSI.SoapWriter's serialization, I use 290 # the machinery used for VOTables and HTML to serialize weird values. 291 # It's in place anyway. 292 293 _wsdlMFRegistry = valuemappers.ValueMapperFactoryRegistry() 294 _registerMF = _wsdlMFRegistry.registerFactory 295 296298 """returns mapper for datetime objects to python time tuples. 299 """ 300 if colProps["dbtype"] in ("date", "datetime"): 301 def mapper(val): 302 return val.timetuple()303 return mapper 304 _registerMF(datetimeMapperFactory) 305307 """returns a SOAP serialization of the DataSet data's primary table. 308 """ 309 table = data.getPrimaryTable() 310 tns = base.getMetaText(service, "identifier") 311 class Row(TC.Struct): 312 def __init__(self): 313 TC.Struct.__init__(self, None, [ 314 sqltypeToTC(f.type)(pname=(tns, f.name)) 315 for f in table.tableDef], 316 pname=(tns, "outRow"))317 318 class Table(list): 319 typecode = TC.Array((tns, 'outRow'), Row(), 320 pname=(tns, 'outList')) 321 322 mapped = Table( 323 base.SerManager(table, mfRegistry=_wsdlMFRegistry).getMappedValues()) 324 sw = ZSI.SoapWriter(nsdict={"tns": tns}) 325 sw.serialize(mapped).close() 326 return str(sw) 327 328330 """returns an XML-clean version of obj's unicode representation. 331 332 I'd expect ZSI to worry about this, but clearly they don't. 333 """ 334 return unicode(obj 335 ).replace("&", "&").replace("<", "<").replace(">", ">")336 337339 if isinstance(exc, base.ValidationError): 340 val = ZSI.Fault(ZSI.Fault.Client, unicodeXML(exc)) 341 else: 342 val = ZSI.Fault(ZSI.Fault.Server, unicodeXML(exc)) 343 return val.AsSOAP( 344 nsdict={"tns": base.getMetaText(service, "identifier")})345
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Thu May 2 07:29:09 2019 | http://epydoc.sourceforge.net |