Entry
Howto develop plugins/adaptors for CM AO's to de-risk implementation specifics?
Howto develop plugins/adaptors to provide a mechanism to version control deployed code?
Oct 14th, 2004 07:30
Kalu Ral, Engineer TCSI, http://www.consolidate-loan-student.com , http://www.0-apr-credit-card.biz , http://www.clearpathoverseas.com
Occasionally it is neccessary to model an AO, but to delegate the
implementation of the AO's behaviour to a secodary plugin/adaptor.
In this hypothetical scenario, it may be disired to implement a
behaviour using IOS in Release 1, and change the implementation to use
SNMP in Release 2. This plugin mechanism allows such a behaviour
without having to recompile anything and without having to stop/re-
start
the management system,
Assumptions:
- operation signatures remain unchanged from version to version.
Otherwise, a recompilation is mandatory.
- define the nomenclature to identify the python module. E.g.,
new_python_module = className + version
Step 1:
- AO class must support a attribute to enable pluging version.
In this example, we use the attribute "version"
// File: Topo.py
// Extend Topo.py with custom AO defination.
// Example AO defination that supports the "version" attribute.
CLASS cRouter:
{
rw string version; /* must be provided by EMS user */
virtual modifier ValidatePlugin(OUT stringList resultSet) %
TCSI_language="Python";
};
Step 2:
- Modify the generated cRouter.py code to make use of the dispatcher
mechanism.
- This file will never require future modifications as all
implementation specifics will be implemented in the appropriate
plugin.
Hence, this is write once ONLY!!
// File cRouter.py
import _DynServerInternals
from DynServer import moBaseMo
from Osp import OspError
import sys
CODE = 200
INDEX_PLUGIN_NOT_SPECIFIED = 1
INDEX_PLUGIN_NOT_FOUND = 2
DEFAULT_ERR = 'Operation FAILED. '
class cRouterCpp(moBaseMo):
'ops to make direct call to C++ implementation from python'
def ValidatePlugin(self):
return _DynServerInternals.InvokeCpp(self, self._inst, 10064)
class cRouterMix(cRouterCpp):
'Op implementations with TCSI_language="Python"'
def ValidatePlugin(self):
# Obtain the plugin by invoking the getDispatcherPlugin()
# operation and invoke the AO operation.
# WARNING: The signature for the AO operation must be
# identical.
return self.getDispatcherPlugin().ValidatePlugin()
def getDispatcherPlugin(self):
# This internal method is utilized to import the appropriate
# plugin version and return a handle of the plugin to the
# invoking operation.
# Alternatively, this block of code can be implemented in
# a separate python utility module. It is added here for
# simplicity reasons only.
# Check to ensure "version" attribute is consistent.
if not self.version:
errStr = "%s: plugin version not specified, " % (self.name,)
raise OspError(CODE, INDEX_PLUGIN_NOT_SPECIFIED, errStr)
# Note: The nomenclature to identify the python module
# is className + "version"
mod_name = "cRouter" + self.version
# Import the plugin
try:
# Assumes 1 class per module ONLY!!
mod = __import__(mod_name)
cls = getattr(mod, mod_name)
except:
errStr = 'Cannot get/find plugin "%s"' % (mod_name,)
raise OspError(CODE, INDEX_PLUGIN_NOT_FOUND, errStr)
# apply()ing the class object (cls) to an argument list
# constructs an instance of the class (Python magic)
_temp = apply(cls,)
# returns the instance of the plugin.
return _temp
Step 3:
- Implement a plugin
- Ensure the className in the plugin and the filename of this python
module are identical. In this example,
fileName = cRouterAB02.py
className= cRouterAB02
// File: cRouterAB02.py
print 'loading cRouterAB02.py'
VERSION = 'AB02'
class cRouterAB02:
'Op implementations with TCSI_language="Python"'
def ValidatePlugin(self):
# Insert code for the operation.
resultSet = []
resultSet.append("The plugin version is....")
resultSet.append(VERSION)
return (resultSet,)
Step 4:
- Using PyOsp, create an instance of cRouter
>a = Topo.cRouter(name = "cRouter1", version = "AB02")
- Test the behaviour
>a.version
AB02
>a.ValidatePlugin()
The plugin version is
AB02
>a.version = 'AA01'
>a.ValidatePlugin()
OspError: Cannot get/find plugin cRouterAA01
- To validate the plugin concept, copy cRouterAB02.py to
cRouterZZZ.py.
Edit cRouterZZZ.py and change all occurences of "AB02" to
"ZZZ".
Then...
>a.version = "ZZZ"
>a.version
ZZZ
>a.ValidatePlugin()
The plugin version is
ZZZ
This proves that the new plugin was dispatched without having to
restart
the TOM, etc.