1# VMware vSphere Python SDK
2# Copyright (c) 2008-2016 VMware, Inc. All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16"""
17This module provides convinent fns related to ManagedMethodExecutor
18"""
19__author__ = "VMware, Inc."
20
21from pyVmomi import VmomiSupport, SoapAdapter, vmodl
22from .SoapAdapter import SoapStubAdapterBase, SerializeToUnicode, Deserialize
23
24## ManagedMethodExecutor soap stub adapter
25#
26class MMESoapStubAdapter(SoapStubAdapterBase):
27   """ Managed method executor stub adapter  """
28
29   ## Constructor
30   #
31   # The endpoint can be specified individually as either a host/port
32   # combination, or with a URL (using a url= keyword).
33   #
34   # @param self self
35   # @param mme  managed method executor
36   def __init__(self, mme):
37      stub = mme._stub
38      SoapStubAdapterBase.__init__(self, version=stub.version)
39      self.mme = mme
40
41   ## Compute the version information for the specified namespace
42   #
43   # @param ns the namespace
44   def ComputeVersionInfo(self, version):
45      SoapStubAdapterBase.ComputeVersionInfo(self, version)
46      self.versionId = self.versionId[1:-1]
47
48   ## Invoke a managed method, with _ExecuteSoap. Wohooo!
49   #
50   # @param self self
51   # @param mo the 'this'
52   # @param info method info
53   # @param args arguments
54   def InvokeMethod(self, mo, info, args):
55      # Serialize parameters to soap parameters
56      methodArgs = None
57      if info.params:
58         methodArgs = vmodl.Reflect.ManagedMethodExecutor.SoapArgument.Array()
59         for param, arg in zip(info.params, args):
60            if arg is not None:
61               # Serialize parameters to soap snippets
62               soapVal = SerializeToUnicode(val=arg, info=param, version=self.version)
63
64               # Insert argument
65               soapArg = vmodl.Reflect.ManagedMethodExecutor.SoapArgument(
66                                                  name=param.name, val=soapVal)
67               methodArgs.append(soapArg)
68
69      moid = mo._GetMoId()
70      version = self.versionId
71      methodName = VmomiSupport.GetVmodlName(info.type) + "." + info.name
72
73      # Execute method
74      result = self.mme.ExecuteSoap(moid=moid,
75                                    version=version,
76                                    method=methodName,
77                                    argument=methodArgs)
78      return self._DeserializeExecutorResult(result, info.result)
79
80   ## Invoke a managed property accessor
81   #
82   # @param self self
83   # @param mo the 'this'
84   # @param info property info
85   def InvokeAccessor(self, mo, info):
86      moid = mo._GetMoId()
87      version = self.versionId
88      prop = info.name
89
90      # Fetch property
91      result = self.mme.FetchSoap(moid=moid, version=version, prop=prop)
92      return self._DeserializeExecutorResult(result, info.type)
93
94   ## Deserialize result from ExecuteSoap / FetchSoap
95   #
96   # @param self self
97   # @param result result from ExecuteSoap / FetchSoap
98   # @param resultType Expected result type
99   def _DeserializeExecutorResult(self, result, resultType):
100      obj = None
101      if result:
102         # Parse the return soap snippet. If fault, raise exception
103         if result.response:
104            # Deserialize back to result
105            obj = Deserialize(result.response, resultType, stub=self)
106         elif result.fault:
107            # Deserialize back to fault (or vmomi fault)
108            fault = Deserialize(result.fault.faultDetail,
109                                object,
110                                stub=self)
111            # Silent pylint
112            raise fault # pylint: disable-msg=E0702
113         else:
114            # Unexpected: result should have either response or fault
115            msg = "Unexpected execute/fetchSoap error"
116            reason = "execute/fetchSoap did not return response or fault"
117            raise vmodl.Fault.SystemError(msg=msg, reason=reason)
118      return obj
119