From a3f5b13a0970498ca1d0564fc009ef30aca1bf8f Mon Sep 17 00:00:00 2001 From: Stanislav Grozev Date: Mon, 31 Mar 2014 11:47:30 +0300 Subject: [PATCH 1/3] Implement KeyAnyValue serialization. Fix integer/long serialization. This allows operations with Host Profiles to succeed. --- lib/rbvmomi/basic_types.rb | 10 ++++++++++ lib/rbvmomi/connection.rb | 20 ++++++++++++++++++-- lib/rbvmomi/deserialization.rb | 4 +++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/rbvmomi/basic_types.rb b/lib/rbvmomi/basic_types.rb index ac1a19b4..8434718b 100644 --- a/lib/rbvmomi/basic_types.rb +++ b/lib/rbvmomi/basic_types.rb @@ -351,6 +351,16 @@ def initialize x def to_s @val.to_s end + + def inspect + @val + end + + def == o + @val.to_i == o + end + + alias eql? == end class KeyValue diff --git a/lib/rbvmomi/connection.rb b/lib/rbvmomi/connection.rb index a9b4e915..21a3f7a6 100644 --- a/lib/rbvmomi/connection.rb +++ b/lib/rbvmomi/connection.rb @@ -117,6 +117,21 @@ def obj2xml xml, name, type, is_array, o, attrs={} expected = type(type) fail "expected array for '#{name}', got #{o.class.wsdl_name}" if is_array and not (o.is_a? Array or (o.is_a? Hash and expected == BasicTypes::KeyValue)) case o + when VIM::KeyAnyValue + xml.tag! name, attrs do + xml.tag! 'key', o.key.to_s + if o.value.kind_of? Array + types = o.value.map { |e| e.class }.uniq + fail "Expected homogenous array for '#{name}', got '#{types}'" unless types.count == 1 + xml.tag! 'value', { 'xsi:type' => "ArrayOf#{types.first}" } do + o.value.each do |v| + xml.tag! v.class.to_s.downcase, v.to_s + end + end + else + obj2xml xml, 'value', BasicTypes::AnyType.wsdl_name, false, o.value, {} + end + end when Array, BasicTypes::KeyValue if o.is_a? BasicTypes::KeyValue and expected != BasicTypes::KeyValue fail "expected #{expected.wsdl_name} for '#{name}', got KeyValue" @@ -180,7 +195,7 @@ def obj2xml xml, name, type, is_array, o, attrs={} when Time attrs['xsi:type'] = 'xsd:dateTime' if expected == BasicTypes::AnyType xml.tag! name, o.iso8601, attrs - when BasicTypes::Int + when BasicTypes::Int, Fixnum, Integer attrs['xsi:type'] = 'xsd:int' xml.tag! name, o.to_s, attrs else fail "unexpected object class #{o.class} for '#{name}'" @@ -199,7 +214,8 @@ def self.type name when :anyType then BasicTypes::AnyType when :boolean then BasicTypes::Boolean when :string then String - when :int, :long, :short, :byte then Integer + when :long then Integer + when :int, :short, :byte then BasicTypes::Int when :float, :double then Float when :dateTime then Time when :base64Binary then BasicTypes::Binary diff --git a/lib/rbvmomi/deserialization.rb b/lib/rbvmomi/deserialization.rb index 99c3441e..343f7840 100644 --- a/lib/rbvmomi/deserialization.rb +++ b/lib/rbvmomi/deserialization.rb @@ -20,7 +20,7 @@ class NewDeserializer 'xsd:byte' => :int, 'xsd:short' => :int, 'xsd:int' => :int, - 'xsd:long' => :int, + 'xsd:long' => :long, 'xsd:float' => :float, 'xsd:dateTime' => :date, 'PropertyPath' => :string, @@ -59,6 +59,8 @@ def deserialize node, type=nil when :boolean node.content == '1' || node.content == 'true' when :int + BasicTypes::Int.new(node.content) + when :long node.content.to_i when :float node.content.to_f From bf3606be4ef4e65cda360160b4be5b518467b4d2 Mon Sep 17 00:00:00 2001 From: Stanislav Grozev Date: Mon, 31 Mar 2014 14:13:22 +0300 Subject: [PATCH 2/3] Subclass RbVmomi::BasicTypes::Int from Integer, so normal operations (addition, substraction, etc.) with integers will work fine. --- lib/rbvmomi/basic_types.rb | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/rbvmomi/basic_types.rb b/lib/rbvmomi/basic_types.rb index 8434718b..f37b89a3 100644 --- a/lib/rbvmomi/basic_types.rb +++ b/lib/rbvmomi/basic_types.rb @@ -341,13 +341,15 @@ class ::Float def self.wsdl_name; 'xsd:float' end end -class Int +# Subclassing Integer directly isn't really possible since it isn't a normal +# Ruby object per se. +class Int < Object def self.wsdl_name; 'xsd:int' end - + def initialize x @val = x end - + def to_s @val.to_s end @@ -361,6 +363,16 @@ def == o end alias eql? == + + def respond_to? + @val.respond_to? + end + + private + + def method_missing(method, *args, &block) + @val.send(method, *args, &block) + end end class KeyValue From 0ffae074db01dd358b7af76b134f0a014865c629 Mon Sep 17 00:00:00 2001 From: Stanislav Grozev Date: Mon, 31 Mar 2014 14:57:45 +0300 Subject: [PATCH 3/3] Missing method name in Int#respond_to? --- lib/rbvmomi/basic_types.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rbvmomi/basic_types.rb b/lib/rbvmomi/basic_types.rb index f37b89a3..67b5f4c7 100644 --- a/lib/rbvmomi/basic_types.rb +++ b/lib/rbvmomi/basic_types.rb @@ -364,8 +364,8 @@ def == o alias eql? == - def respond_to? - @val.respond_to? + def respond_to? method + @val.respond_to? method end private