faqts : Computers : Management Systems : TCSI : Catalant : Server Development

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

4 of 10 people (40%) answered Yes
Recently 1 of 7 people (14%) answered Yes

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.