E
emcconne
I am new to Ruby and am evaluating it for a project that would replace
and extend existing Perl code. I am using wsdl2ruby to generate a
client stub with associated classes for a web service. Most of the
basic calls more fine but the more complex method calls that take
parameter "anyType" do not work so well. It appears that the type is
not getting set in the SOAP message generated by ruby. However, the
perl code does allow me to set the type (manually by calling
SOAP:ata -> type using SOAP::Lite). Below is the relevant code and
generated messages:
-----RELEVANT WSDL SECTION----
<xsd:element name="Create">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="handle"
type="xsd:string" vma:auth="Configure"/>
<xsd:element maxOccurs="1" minOccurs="1" name="name"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="type"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="initial"
type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element
-----GENERATED CLASSES-----
# {urn:vma1}Create
class Create
@@schema_type = "Create"
@@schema_ns = "urn:vma1"
@@schema_qualified = "true"
@@schema_element = [["handle", "SOAP::SOAPString"], ["name",
"SOAP::SOAPString"], ["type", "SOAP::SOAPString"], ["initial",
"anyType"]]
attr_accessor :handle
attr_accessor :name
attr_accessor :type
attr_accessor :initial
def initialize(handle = nil, name = nil, type = nil, initial = nil)
@handle = handle
@name = name
@type = type
@initial = initial
end
end
----FROM DRIVER -----
class VmaPortType < ::SOAP::RPC:river
DefaultEndpointUrl = "http://xxx.xxx.xxx:8080/"
MappingRegistry = ::SOAP::Mapping::Registry.new
Methods = [
[ "",
"create",
[ ["in", "parameters", ["::SOAP::SOAPElement", "urn:vma1",
"Create"], true],
["out", "parameters", ["::SOAP::SOAPElement", "urn:vma1",
"CreateResponse"], true] ],
{ :request_style => :document, :request_use => :literal,
:response_style => :document, :response_use => :literal }
]
]
def initialize(endpoint_url = nil)
endpoint_url ||= DefaultEndpointUrl
super(endpoint_url, nil)
self.mapping_registry = MappingRegistry
init_methods
end
private
def init_methods
Methods.each do |definitions|
opt = definitions.last
if opt[:request_style] == :document
add_document_operation(*definitions)
else
add_rpc_operation(*definitions)
qname = definitions[0]
name = definitions[2]
if qname.name != name and qname.name.capitalize ==
name.capitalize
::SOAP::Mapping.define_singleton_method(self, qname.name) do
|*arg|
__send__(name, *arg)
end
end
end
end
end
end
-----FROM CLIENT-----
require 'vmaDriver.rb'
endpoint_url = ARGV.shift
$KCODE = 'UTF8'
obj = VmaPortType.new(endpoint_url)
obj.generate_explicit_type = true
# run ruby with -d to see SOAP widumps.
obj.wiredump_dev = STDERR
parameter=nil
vmlogin=Login.new("emcconne", "oh,bother")
puts obj.login(vmlogin)
vmcenter=ResolvePath.new("/vcenter/Testdrive_Farm")
vmdomain=obj.resolvePath(vmcenter).returnval
vmpath=ResolvePath.new("/host/192.168.0.2")
vmhost=obj.resolvePath(vmpath).returnval
vmcpuinfo=VirtualCPUInfo.new(2,"")
vmmeminfo=VirtualMemoryInfo.new(512,"")
vmhardware=VirtualHardware.new(vmcpuinfo,vmmeminfo,"","",[],[],[])
vmspec=VirtualMachineSpec.new(vmhost,"linux","",vmhardware)
vmcreate=Create.new(vmdomain,"rubyvm","VirtualMachine",vmspec)
puts obj.create(vmcreate)
----- GENERATED MESSAGE -----
<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<Create xmlns="urn:vma1">
<handle>vma-domain-00000000001</handle>
<name>rubyvm</name>
<type>VirtualMachine</type>
<initial>
<host>vma-host-00000000002</host>
<guestOS>linux</guestOS>
<file></file>
<hardware>
<cpu>
<count>2</count>
<controls></controls>
</cpu>
<memory>
<sizeMb>512</sizeMb>
<controls></controls>
</memory>
<net></net>
<disk></disk>
</hardware>
</initial>
</Create>
</env:Body>
</env:Envelope>
-------WORKING PERL MESSAGE ------
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope
xmlns:namesp1="http://namespaces.soaplite.com/perl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Create xmlns="urn:vma1">
<handle xsi:type="xsd:string">vma-domain-00000000001</handle>
<name xsi:type="xsd:string">perlvm</name>
<type xsi:type="xsd:string">VirtualMachine</type>
<initial xsi:type="namesp1:VirtualMachineSpec">
<host xsi:type="xsd:string">vma-host-00000000002</host>
<guestOS xsi:type="xsd:string">Linux</guestOS>
<hardware>
<cpu>
<count xsi:type="xsd:int">1</count>
</cpu>
<memory>
<sizeMb xsi:type="xsd:int">256</sizeMb>
</memory>
</hardware>
</initial>
</Create>
</soap:Body>
</soap:Envelope>
and extend existing Perl code. I am using wsdl2ruby to generate a
client stub with associated classes for a web service. Most of the
basic calls more fine but the more complex method calls that take
parameter "anyType" do not work so well. It appears that the type is
not getting set in the SOAP message generated by ruby. However, the
perl code does allow me to set the type (manually by calling
SOAP:ata -> type using SOAP::Lite). Below is the relevant code and
generated messages:
-----RELEVANT WSDL SECTION----
<xsd:element name="Create">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="handle"
type="xsd:string" vma:auth="Configure"/>
<xsd:element maxOccurs="1" minOccurs="1" name="name"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="1" name="type"
type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="initial"
type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element
-----GENERATED CLASSES-----
# {urn:vma1}Create
class Create
@@schema_type = "Create"
@@schema_ns = "urn:vma1"
@@schema_qualified = "true"
@@schema_element = [["handle", "SOAP::SOAPString"], ["name",
"SOAP::SOAPString"], ["type", "SOAP::SOAPString"], ["initial",
"anyType"]]
attr_accessor :handle
attr_accessor :name
attr_accessor :type
attr_accessor :initial
def initialize(handle = nil, name = nil, type = nil, initial = nil)
@handle = handle
@name = name
@type = type
@initial = initial
end
end
----FROM DRIVER -----
class VmaPortType < ::SOAP::RPC:river
DefaultEndpointUrl = "http://xxx.xxx.xxx:8080/"
MappingRegistry = ::SOAP::Mapping::Registry.new
Methods = [
[ "",
"create",
[ ["in", "parameters", ["::SOAP::SOAPElement", "urn:vma1",
"Create"], true],
["out", "parameters", ["::SOAP::SOAPElement", "urn:vma1",
"CreateResponse"], true] ],
{ :request_style => :document, :request_use => :literal,
:response_style => :document, :response_use => :literal }
]
]
def initialize(endpoint_url = nil)
endpoint_url ||= DefaultEndpointUrl
super(endpoint_url, nil)
self.mapping_registry = MappingRegistry
init_methods
end
private
def init_methods
Methods.each do |definitions|
opt = definitions.last
if opt[:request_style] == :document
add_document_operation(*definitions)
else
add_rpc_operation(*definitions)
qname = definitions[0]
name = definitions[2]
if qname.name != name and qname.name.capitalize ==
name.capitalize
::SOAP::Mapping.define_singleton_method(self, qname.name) do
|*arg|
__send__(name, *arg)
end
end
end
end
end
end
-----FROM CLIENT-----
require 'vmaDriver.rb'
endpoint_url = ARGV.shift
$KCODE = 'UTF8'
obj = VmaPortType.new(endpoint_url)
obj.generate_explicit_type = true
# run ruby with -d to see SOAP widumps.
obj.wiredump_dev = STDERR
parameter=nil
vmlogin=Login.new("emcconne", "oh,bother")
puts obj.login(vmlogin)
vmcenter=ResolvePath.new("/vcenter/Testdrive_Farm")
vmdomain=obj.resolvePath(vmcenter).returnval
vmpath=ResolvePath.new("/host/192.168.0.2")
vmhost=obj.resolvePath(vmpath).returnval
vmcpuinfo=VirtualCPUInfo.new(2,"")
vmmeminfo=VirtualMemoryInfo.new(512,"")
vmhardware=VirtualHardware.new(vmcpuinfo,vmmeminfo,"","",[],[],[])
vmspec=VirtualMachineSpec.new(vmhost,"linux","",vmhardware)
vmcreate=Create.new(vmdomain,"rubyvm","VirtualMachine",vmspec)
puts obj.create(vmcreate)
----- GENERATED MESSAGE -----
<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<Create xmlns="urn:vma1">
<handle>vma-domain-00000000001</handle>
<name>rubyvm</name>
<type>VirtualMachine</type>
<initial>
<host>vma-host-00000000002</host>
<guestOS>linux</guestOS>
<file></file>
<hardware>
<cpu>
<count>2</count>
<controls></controls>
</cpu>
<memory>
<sizeMb>512</sizeMb>
<controls></controls>
</memory>
<net></net>
<disk></disk>
</hardware>
</initial>
</Create>
</env:Body>
</env:Envelope>
-------WORKING PERL MESSAGE ------
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope
xmlns:namesp1="http://namespaces.soaplite.com/perl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Create xmlns="urn:vma1">
<handle xsi:type="xsd:string">vma-domain-00000000001</handle>
<name xsi:type="xsd:string">perlvm</name>
<type xsi:type="xsd:string">VirtualMachine</type>
<initial xsi:type="namesp1:VirtualMachineSpec">
<host xsi:type="xsd:string">vma-host-00000000002</host>
<guestOS xsi:type="xsd:string">Linux</guestOS>
<hardware>
<cpu>
<count xsi:type="xsd:int">1</count>
</cpu>
<memory>
<sizeMb xsi:type="xsd:int">256</sizeMb>
</memory>
</hardware>
</initial>
</Create>
</soap:Body>
</soap:Envelope>