Merge pull request #398 from tianhao64/master
Temporarily workaround issue #182 by creating dummy managed method
This commit is contained in:
@@ -734,7 +734,10 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
|
||||
# val in Method val is not namespace qualified
|
||||
# However, this doesn't hurt to strip out namespace
|
||||
ns, name = self.GetNSAndWsdlname(data)
|
||||
obj = GuessWsdlMethod(name)
|
||||
try:
|
||||
obj = GuessWsdlMethod(name)
|
||||
except KeyError:
|
||||
obj = UncallableManagedMethod(name)
|
||||
elif obj is bool:
|
||||
if data == "0" or data.lower() == "false":
|
||||
obj = bool(False)
|
||||
|
@@ -307,6 +307,8 @@ def FormatObject(val, info=Object(name="", type=object, flags=0), indent=0):
|
||||
result = "(%s) []" % itemType.__name__
|
||||
elif isinstance(val, type):
|
||||
result = val.__name__
|
||||
elif isinstance(val, UncallableManagedMethod):
|
||||
result = val.name
|
||||
elif isinstance(val, ManagedMethod):
|
||||
result = '%s.%s' % (val.info.type.__name__, val.info.name)
|
||||
elif isinstance(val, bool):
|
||||
@@ -588,6 +590,15 @@ class ManagedMethod(Curry):
|
||||
Curry.__init__(self, ManagedObject._InvokeMethod, info)
|
||||
self.info = info
|
||||
|
||||
# Method used to represent any unknown wsdl method returned by server response.
|
||||
# Server may return unknown method name due to server defects or newer version.
|
||||
class UncallableManagedMethod(ManagedMethod):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
raise Exception("Managed method {} is not available".format(self.name))
|
||||
|
||||
## Create the vmodl.MethodFault type
|
||||
#
|
||||
# This type must be generated dynamically because it inherits from
|
||||
@@ -1038,9 +1049,15 @@ class UnknownWsdlTypeError(KeyError):
|
||||
# @return type if found in any one of the name spaces else throws KeyError
|
||||
def GuessWsdlType(name):
|
||||
with _lazyLock:
|
||||
# Because the types are lazily loaded, if some name is present
|
||||
# in multiple namespaces, we will load the first type that we
|
||||
# encounter and return it.
|
||||
# Some types may exist in multiple namespaces, and returning
|
||||
# the wrong one will cause a deserialization error.
|
||||
# Since in python3 the order of entries in set is not deterministic,
|
||||
# we will try to get the type from vim25 namespace first.
|
||||
try:
|
||||
return GetWsdlType(XMLNS_VMODL_BASE, name)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
for ns in _wsdlTypeMapNSs:
|
||||
try:
|
||||
return GetWsdlType(ns, name)
|
||||
@@ -1231,6 +1248,15 @@ def GetWsdlMethod(ns, wsdlName):
|
||||
# KeyError
|
||||
def GuessWsdlMethod(name):
|
||||
with _lazyLock:
|
||||
# Some methods may exist in multiple namespaces, and returning
|
||||
# the wrong one will cause a deserialization error.
|
||||
# Since in python3 the order of entries in set is not deterministic,
|
||||
# we will try to get the method from vim25 namespace first.
|
||||
try:
|
||||
return GetWsdlMethod(XMLNS_VMODL_BASE, name)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
for ns in _wsdlMethodNSs:
|
||||
try:
|
||||
return GetWsdlMethod(ns, name)
|
||||
|
78
tests/files/unknown_method.xml
Normal file
78
tests/files/unknown_method.xml
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<soapenv:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<soapenv:Body>
|
||||
<ReadNextTasksResponse xmlns="urn:vim25">
|
||||
<returnval>
|
||||
<key>task-3996443</key>
|
||||
<task type="Task">task-3996443</task>
|
||||
<description>
|
||||
<key>com.vmware.vdp2.task.description</key>
|
||||
<arg>
|
||||
<key>workOrderId</key>
|
||||
<value xsi:type="xsd:string">cp.20141020150650</value>
|
||||
</arg>
|
||||
</description>
|
||||
<descriptionId>com.vmware.vdp2.integritycheck</descriptionId>
|
||||
<entity type="VirtualMachine">vm-133364</entity>
|
||||
<entityName>VDP3</entityName>
|
||||
<state>running</state>
|
||||
<cancelled>false</cancelled>
|
||||
<cancelable>true</cancelable>
|
||||
<reason xsi:type="TaskReasonUser">
|
||||
<userName>vmware\\sa-vdp3</userName>
|
||||
</reason>
|
||||
<queueTime>2014-10-20T15:09:08.789999Z</queueTime>
|
||||
<startTime>2014-10-20T15:09:09.073Z</startTime>
|
||||
<eventChainId>21691195</eventChainId>
|
||||
</returnval>
|
||||
<returnval>
|
||||
<key>task-1178117</key>
|
||||
<task type="Task">task-1178117</task>
|
||||
<descriptionId>com.vmware.vcIntegrity.CheckNotificationTask</descriptionId>
|
||||
<entity type="Folder">group-d1</entity>
|
||||
<entityName>Datacenters</entityName>
|
||||
<state>queued</state>
|
||||
<cancelled>false</cancelled>
|
||||
<cancelable>true</cancelable>
|
||||
<reason xsi:type="TaskReasonSchedule">
|
||||
<name>VMware vSphere Update Manager Check Notification</name>
|
||||
<scheduledTask type="ScheduledTask">schedule-2</scheduledTask>
|
||||
</reason>
|
||||
<queueTime>2013-01-08T14:12:01.556999Z</queueTime>
|
||||
<eventChainId>3410272</eventChainId>
|
||||
</returnval>
|
||||
<returnval>
|
||||
<key>task-746590</key>
|
||||
<task type="Task">task-746590</task>
|
||||
<name>LeaseMapDiskRegion</name>
|
||||
<descriptionId>host.DiskManager.Lease.MapDiskRegion</descriptionId>
|
||||
<entity type="VirtualMachine">vm-982</entity>
|
||||
<entityName>Applicure</entityName>
|
||||
<state>queued</state>
|
||||
<cancelled>false</cancelled>
|
||||
<cancelable>false</cancelable>
|
||||
<reason xsi:type="TaskReasonUser">
|
||||
<userName>VMWARE\\sa-veeam1</userName>
|
||||
</reason>
|
||||
<queueTime>2012-09-27T12:03:03.412999Z</queueTime>
|
||||
<eventChainId>2325872</eventChainId>
|
||||
</returnval>
|
||||
<returnval>
|
||||
<key>task-56327</key>
|
||||
<task type="Task">task-56327</task>
|
||||
<name>LeaseMapDiskRegion</name>
|
||||
<descriptionId>host.DiskManager.Lease.MapDiskRegion</descriptionId>
|
||||
<entity type="VirtualMachine">vm-1010</entity>
|
||||
<entityName>vCD-Oracle</entityName>
|
||||
<state>queued</state>
|
||||
<cancelled>false</cancelled>
|
||||
<cancelable>false</cancelable>
|
||||
<reason xsi:type="TaskReasonUser">
|
||||
<userName>VMWARE\\sa-veeam1</userName>
|
||||
</reason>
|
||||
<queueTime>2012-02-27T10:56:50.656999Z</queueTime>
|
||||
<eventChainId>345916</eventChainId>
|
||||
</returnval>
|
||||
</ReadNextTasksResponse>
|
||||
</soapenv:Body>
|
||||
</soapenv:Envelope>
|
33
tests/test_deserializer.py
Normal file
33
tests/test_deserializer.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# VMware vSphere Python SDK
|
||||
# Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from pyVmomi import vim
|
||||
from pyVmomi.SoapAdapter import SoapStubAdapter, SoapResponseDeserializer
|
||||
import unittest
|
||||
|
||||
|
||||
class DeserializerTests(unittest.TestCase):
|
||||
|
||||
def test_deserialize_unknown_managed_method(self):
|
||||
with open('tests/files/unknown_method.xml', 'rb') as f:
|
||||
data = f.read()
|
||||
stub = SoapStubAdapter(version="vim.version.version6")
|
||||
deserializer = SoapResponseDeserializer(stub)
|
||||
result = vim.TaskHistoryCollector._GetMethodInfo("ReadNext").result
|
||||
obj = deserializer.Deserialize(data, result)
|
||||
print(obj)
|
||||
with self.assertRaisesRegexp(Exception, "Managed method LeaseMapDiskRegion is not available"):
|
||||
obj[-1].name()
|
||||
|
Reference in New Issue
Block a user