3 # Sapan Bhatia <sapanb@cs.princeton.edu>
5 # Generates a WSDL for geniwrapper
7 # - Invalid for the following reasons
8 # - The types are python types, not WSDL types
13 import xml.dom.minidom
19 from geni.util.auth import Auth
20 from geni.util.parameter import Parameter,Mixed
27 class SoapError(Exception):
28 def __init__(self, value):
31 return repr(self.value)
39 def name_vector_type(acc,arg):
40 name = name_complex_type(elt)
41 complex_types[arg]=name
45 def name_complex_type(arg):
46 if (instanceof(arg, Mixed)):
47 inner_types = reduce(name_vector_type, arg)
50 type_name = "Type%d"%num_types
51 complex_type = types.firstChild.appendChild(types.createElement("wsdl:complexType"))
52 complex_type.setAttribute("name", type_name)
54 choice = complex_type.appendChild(complex_type.createElement("xsd:choice"))
55 choice.appendChild(choice.createElement("element"))
57 choice.setAttribute("name", "Foobar")
58 choice.setAttribute("minOccurs","1")
59 choice.setAttribute("maxOccurs","1")
60 choice.setAttribute("type", "tns:$i")
64 return (name_simple_type(arg))
66 def name_simple_type(arg):
68 if arg_type == IntType or arg_type == LongType:
70 elif arg_type == bool:
72 elif arg_type == FloatType:
74 elif arg_type in StringTypes:
78 raise SoapError, "Cannot handle %s objects" % arg_type
81 return (name_complex_type(arg))
83 def add_wsdl_ports_and_bindings (wsdl):
84 for method in apistub.methods:
85 # Skip system. methods
86 if "system." in method:
89 function = apistub.callable(method) # Commented documentation
90 #lines = ["// " + line.strip() for line in function.__doc__.strip().split("\n")]
91 #print "\n".join(lines)
95 in_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
96 in_el.setAttribute("name", method + "_in")
98 for service_name in function.interfaces:
99 if (services.has_key(service_name)):
100 if (not method in services[service_name]):
101 services[service_name].append(method)
103 services[service_name]=[method]
107 if (function.accepts):
108 (min_args, max_args, defaults) = function.args()
109 for (argname,argtype) in zip(max_args,function.accepts):
110 arg_part = in_el.appendChild(wsdl.createElement("wsdl:part"))
111 arg_part.setAttribute("name", argname)
112 arg_part.setAttribute("type", param_type(argtype))
115 return_type = function.returns
116 out_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:message"))
117 out_el.setAttribute("name", method + "_out")
118 ret_part = out_el.appendChild(wsdl.createElement("wsdl:part"))
119 ret_part.setAttribute("name", "returnvalue")
120 ret_part.setAttribute("type", param_type(return_type))
122 # Port connecting arguments with return type
124 port_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:portType"))
125 port_el.setAttribute("name", method + "_port")
127 op_el = port_el.appendChild(wsdl.createElement("wsdl:operation"))
128 op_el.setAttribute("name", method)
129 op_el.appendChild(wsdl.createElement("wsdl:input")).setAttribute("message","tns:" + method + "_in")
130 op_el.appendChild(wsdl.createElement("wsdl:output")).setAttribute("message","tns:" + method + "_out")
134 bind_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:binding"))
135 bind_el.setAttribute("name", method + "_binding")
136 bind_el.setAttribute("type", "tns:" + method + "_port")
138 soap_bind = bind_el.appendChild(wsdl.createElement("soap:binding"))
139 soap_bind.setAttribute("style", "rpc")
140 soap_bind.setAttribute("transport","http://schemas.xmlsoap.org/soap/http")
143 wsdl_op = bind_el.appendChild(wsdl.createElement("wsdl:operation"))
144 wsdl_op.setAttribute("name", method)
145 wsdl_op.appendChild(wsdl.createElement("soap:operation")).setAttribute("soapAction",
149 wsdl_input = wsdl_op.appendChild(wsdl.createElement("wsdl:input"))
150 input_soap_body = wsdl_input.appendChild(wsdl.createElement("soap:body"))
151 input_soap_body.setAttribute("use", "encoded")
152 input_soap_body.setAttribute("namespace", "urn:" + method)
153 input_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
156 wsdl_output = wsdl_op.appendChild(wsdl.createElement("wsdl:output"))
157 output_soap_body = wsdl_output.appendChild(wsdl.createElement("soap:body"))
158 output_soap_body.setAttribute("use", "encoded")
159 output_soap_body.setAttribute("namespace", "urn:" + method)
160 output_soap_body.setAttribute("encodingStyle","http://schemas.xmlsoap.org/soap/encoding/")
163 def add_wsdl_service(wsdl):
164 for service in services.keys():
165 service_el = wsdl.firstChild.appendChild(wsdl.createElement("wsdl:service"))
166 service_el.setAttribute("name", service)
168 for method in services[service]:
170 servport_el = service_el.appendChild(wsdl.createElement("wsdl:port"))
171 servport_el.setAttribute("name", name + "_port")
172 servport_el.setAttribute("binding", "tns:" + name + "_binding")
174 soapaddress = servport_el.appendChild(wsdl.createElement("soap:address"))
175 soapaddress.setAttribute("location", "%s/%s" % (globals.plc_ns,service))
178 def get_wsdl_definitions():
179 wsdl_text_header = """
181 name="auto_generated"
183 xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
185 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
186 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"/>""" % (globals.plc_ns,globals.plc_ns)
188 wsdl = xml.dom.minidom.parseString(wsdl_text_header)
194 types = get_wsdl_definitions()
195 wsdl = get_wsdl_definitions()
196 add_wsdl_ports_and_bindings(wsdl)
197 add_wsdl_service(wsdl)
200 xml.dom.ext.PrettyPrint(wsdl)