Hi Hans,  Anders and Srinivas,

 

Happy new year !!!

I wish you will be healthy and happiness in 2018.

 

I already  answered Hans's question, how can I test for this patch.

Please spend a little time help me review for this patch. Ticket-2681 
<https://sourceforge.net/p/opensaf/tickets/2681/>  depends on this patch.

 

Regards,

Hieu

 

-----Original Message-----
From: Hieu Nguyen [mailto:[email protected]] 
Sent: Wednesday, December 20, 2017 8:16 AM
To: 'Hans Nordebäck' <[email protected]>; 
'[email protected]' <[email protected]>; 
'[email protected]' <[email protected]>
Cc: '[email protected]' <[email protected]>
Subject: RE: [PATCH 1/1] pyosaf: refactor IMM utils [#2683]

 

Hi Hans,

 

Thank for your reply.

I have been modified /samples in pyosaf to test. That's in attached file.

 

Regards,

Hieu

 

-----Original Message-----

From: Hans Nordebäck [ <mailto:[email protected]> 
mailto:[email protected]] 

Sent: Tuesday, December 19, 2017 10:19 PM

To: Hieu Nguyen < <mailto:[email protected]> 
[email protected]>;  <mailto:[email protected]> 
[email protected];  <mailto:[email protected]> 
[email protected]

Cc:  <mailto:[email protected]> 
[email protected]

Subject: Re: [PATCH 1/1] pyosaf: refactor IMM utils [#2683]

 

Hi Hieu,

 

before I start reviewing, a question, how has this patch been tested? 

/Regards HansN

 

 

On 12/19/2017 06:17 AM, Hieu Nguyen wrote:

> + improve OI utils use a separate instance OM agent

> + refactor OM utils with Ccb inheritace OmAgent, rename some classes...

> ---

>   python/pyosaf/utils/immoi/__init__.py    | 531 
> +++++++------------------------

>   python/pyosaf/utils/immoi/agent.py       | 473 +++++++++++++++++++++++++++

>   python/pyosaf/utils/immoi/implementer.py | 145 +++++----

>   python/pyosaf/utils/immom/__init__.py    |   7 +-

>   python/pyosaf/utils/immom/accessor.py    |  31 +-

>   python/pyosaf/utils/immom/agent.py       |  31 +-

>   python/pyosaf/utils/immom/ccb.py         |  71 +----

>   python/pyosaf/utils/immom/iterator.py    |   4 +-

>   python/pyosaf/utils/immom/object.py      |   4 +-

>   9 files changed, 738 insertions(+), 559 deletions(-)

>   create mode 100644 python/pyosaf/utils/immoi/agent.py

> 

> diff --git a/python/pyosaf/utils/immoi/__init__.py 
> b/python/pyosaf/utils/immoi/__init__.py

> index 1b4dece..7247b0e 100644

> --- a/python/pyosaf/utils/immoi/__init__.py

> +++ b/python/pyosaf/utils/immoi/__init__.py

> @@ -22,298 +22,23 @@ Supported functions:

>   - Set/clear/release implementer for class/object

>   - Create/delete/update runtime object

>   - Get class/object attributes

> -- Get IMM error strings

> +- Get/set IMM error strings

> +- Get parent for dn

> +- Get class for dn

> +- Get objects for class

> +- Get available classes of IMM

>   """

>   from __future__ import print_function

> -from copy import deepcopy

> -from ctypes import c_char_p, c_void_p, cast, pointer

> -

> -from pyosaf.saAis import SaStringT, SaVersionT, SaNameT, SaSelectionObjectT, 
> \

> -    unmarshalSaStringTArray, eSaDispatchFlagsT, eSaAisErrorT

> -from pyosaf import saImm, saImmOi

> -from pyosaf.saImm import unmarshalSaImmValue, SaImmAttrNameT,      \

> -    SaImmAttrValuesT_2, SaImmClassNameT, SaImmSearchParametersT_2, \

> -    eSaImmValueTypeT, SaImmAttrDefinitionT_2, SaImmClassCategoryT, \

> -    SaImmAttrModificationT_2, eSaImmAttrModificationTypeT

> -from pyosaf.saImmOi import SaImmOiHandleT, SaImmOiImplementerNameT

> -from pyosaf.utils import immom, log_err, bad_handle_retry, decorate, \

> -    deprecate, initialize_decorate, SafException

> +

> +from pyosaf.saAis import SaSelectionObjectT, eSaAisErrorT

> +from pyosaf.utils import deprecate, SafException

>   from pyosaf.utils.immom.object import ImmObject

> -from pyosaf.utils.immom.ccb import marshal_c_array

> -from pyosaf.utils.immom.iterator import SearchIterator

> +from pyosaf.utils.immoi.agent import OiAgent

>   

>   

> -OPENSAF_IMM_OBJECT = "opensafImm=opensafImm,safApp=safImmService"

>   _oi_agent = None

>   

>   

> -# Decorate pure saImmOi* API's with error-handling retry and exception 
> raising

> -saImmOiInitialize_2 = initialize_decorate(saImmOi.saImmOiInitialize_2)

> -saImmOiSelectionObjectGet = decorate(saImmOi.saImmOiSelectionObjectGet)

> -saImmOiDispatch = decorate(saImmOi.saImmOiDispatch)

> -saImmOiFinalize = decorate(saImmOi.saImmOiFinalize)

> -saImmOiImplementerSet = decorate(saImmOi.saImmOiImplementerSet)

> -saImmOiImplementerClear = decorate(saImmOi.saImmOiImplementerClear)

> -saImmOiClassImplementerSet = decorate(saImmOi.saImmOiClassImplementerSet)

> -saImmOiClassImplementerRelease = \

> -    decorate(saImmOi.saImmOiClassImplementerRelease)

> -saImmOiObjectImplementerSet = decorate(saImmOi.saImmOiObjectImplementerSet)

> -saImmOiObjectImplementerRelease = \

> -    decorate(saImmOi.saImmOiObjectImplementerRelease)

> -saImmOiRtObjectCreate_2 = decorate(saImmOi.saImmOiRtObjectCreate_2)

> -saImmOiRtObjectDelete = decorate(saImmOi.saImmOiRtObjectDelete)

> -saImmOiRtObjectUpdate_2 = decorate(saImmOi.saImmOiRtObjectUpdate_2)

> -saImmOiAdminOperationResult = decorate(saImmOi.saImmOiAdminOperationResult)

> -saImmOiAdminOperationResult_o2 = \

> -    decorate(saImmOi.saImmOiAdminOperationResult_o2)

> -saImmOiAugmentCcbInitialize = decorate(saImmOi.saImmOiAugmentCcbInitialize)

> -saImmOiCcbSetErrorString = decorate(saImmOi.saImmOiCcbSetErrorString)

> -

> -

> -class OiAgent(object):

> -    """ This class acts as a high-level OI agent, providing OI functions to

> -    the users as a higher level, and relieving the users of the need to 
> manage

> -    the life cycle of the OI agent and providing general interface for

> -    Implementer or Applier used

> -    """

> -    def __init__(self, version=None):

> -        """ Constructor for OiAgent class

> -

> -        Args:

> -            version (SaVersionT): OI API version

> -        """

> -        self.handle = None

> -        self.init_version = version if version is not None \

> -            else SaVersionT('A', 2, 15)

> -        self.version = None

> -        self.selection_object = None

> -        self.callbacks = None

> -        global _oi_agent

> -        _oi_agent = self

> -

> -    def _fetch_sel_obj(self):

> -        """ Obtain a selection object (OS file descriptor)

> -

> -        Returns:

> -            SaAisErrorT: Return code of the saImmOiSelectionObjectGet() API

> -        """

> -        rc = saImmOiSelectionObjectGet(self.handle, self.selection_object)

> -        if rc != eSaAisErrorT.SA_AIS_OK:

> -            log_err("saImmOiSelectionObjectGet FAILED - %s" %

> -                    eSaAisErrorT.whatis(rc))

> -

> -        return rc

> -

> -    def initialize(self, callbacks=None):

> -        """ Initialize the IMM OI agent

> -

> -        Args:

> -            callbacks (SaImmOiCallbacksT_2): OI callbacks to register with 
> IMM

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI initialize

> -        """

> -        self.handle = SaImmOiHandleT()

> -        self.selection_object = SaSelectionObjectT()

> -        if callbacks is not None:

> -            self.callbacks = callbacks

> -        self.version = deepcopy(self.init_version)

> -        rc = saImmOiInitialize_2(self.handle, self.callbacks,

> -                                 self.version)

> -        if rc == eSaAisErrorT.SA_AIS_OK:

> -            rc = self._fetch_sel_obj()

> -            if rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:

> -                rc = self.re_initialize()

> -        else:

> -            log_err("saImmOiInitialize_2 FAILED - %s" %

> -                    eSaAisErrorT.whatis(rc))

> -

> -        return rc

> -

> -    @bad_handle_retry

> -    def re_initialize(self):

> -        """ Re-initialize the IMM OI agent

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI initialize

> -        """

> -        self.finalize()

> -        rc = self.initialize()

> -

> -        return rc

> -

> -    def finalize(self):

> -        """ Finalize IMM OI agent handle

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI finalize

> -        """

> -        rc = eSaAisErrorT.SA_AIS_OK

> -        if self.handle is not None:

> -            rc = saImmOiFinalize(self.handle)

> -            if rc != eSaAisErrorT.SA_AIS_OK:

> -                log_err("saImmOiFinalize FAILED - %s" %

> -                        eSaAisErrorT.whatis(rc))

> -            elif rc == eSaAisErrorT.SA_AIS_OK \

> -                    or rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:

> -                # If the Finalize() call returned BAD_HANDLE, the handle 
> should

> -                # already become stale and invalid, so we reset it anyway.

> -                self.handle = None

> -        return rc

> -

> -    def get_selection_object(self):

> -        """ Return the selection object associating with the OI handle

> -

> -        Returns:

> -            SaSelectionObjectT: Selection object associated with the OI 
> handle

> -        """

> -        return self.selection_object

> -

> -    def dispatch(self, flags=eSaDispatchFlagsT.SA_DISPATCH_ALL):

> -        """ Dispatch all queued callbacks

> -

> -        Args:

> -            flags (eSaDispatchFlagsT): Flags specifying dispatch mode

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI dispatch

> -        """

> -        rc = saImmOiDispatch(self.handle, flags)

> -        return rc

> -

> -    def create_runtime_object(self, class_name, parent_name, runtime_obj):

> -        """ Create a runtime object

> -

> -        Args:

> -            class_name (str): Class name

> -            parent_name (str): Parent name

> -            runtime_obj (ImmObject): Runtime object to create

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI create runtime object

> -        """

> -        # Marshall parameters

> -        c_class_name = SaImmClassNameT(class_name)

> -        if parent_name:

> -            c_parent_name = SaNameT(parent_name)

> -        else:

> -            c_parent_name = None

> -

> -        c_attr_values = []

> -

> -        for name, (c_attr_type, values) in runtime_obj.attrs.items():

> -            if values is None:

> -                values = []

> -            elif values == [None]:

> -                values = []

> -

> -            # Make sure all values are in lists

> -            if not isinstance(values, list):

> -                values = [values]

> -

> -            # Create the values struct

> -            c_attr = SaImmAttrValuesT_2()

> -            c_attr.attrName = SaImmAttrNameT(name)

> -            c_attr.attrValueType = c_attr_type

> -            c_attr.attrValuesNumber = len(values)

> -

> -            if not values:

> -                c_attr.attrValues = None

> -            else:

> -                c_attr.attrValues = marshal_c_array(c_attr_type, values)

> -

> -            c_attr_values.append(c_attr)

> -

> -        rc = saImmOiRtObjectCreate_2(self.handle, c_class_name,

> -                                     c_parent_name, c_attr_values)

> -        return rc

> -

> -    def delete_runtime_object(self, dn):

> -        """ Delete a runtime object

> -

> -        Args:

> -            dn (str): Runtime object dn

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI delete runtime object

> -        """

> -        # Marshall the parameter

> -        c_dn = SaNameT(dn)

> -        rc = saImmOiRtObjectDelete(self.handle, c_dn)

> -

> -        return rc

> -

> -    def update_runtime_object(self, dn, attributes):

> -        """ Update the specified object with the requested attribute

> -        modifications

> -

> -        Args:

> -            dn (str): Object dn

> -            attributes (dict): Dictionary of attribute modifications

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI update runtime object

> -        """

> -        # Get the class name for the object

> -        class_name = get_class_name_for_dn(dn)

> -

> -        # Create and marshall attribute modifications

> -        attr_mods = []

> -

> -        for name, values in attributes.items():

> -            if values is None:

> -                print("WARNING: Received no values for %s in %s" % (name, 
> dn))

> -                continue

> -            if not isinstance(values, list):

> -                values = [values]

> -

> -            attr_type = get_attribute_type(name, class_name)

> -            c_attr_mod = SaImmAttrModificationT_2()

> -            c_attr_mod.modType = \

> -                eSaImmAttrModificationTypeT.SA_IMM_ATTR_VALUES_REPLACE

> -            c_attr_mod.modAttr = SaImmAttrValuesT_2()

> -            c_attr_mod.modAttr.attrName = SaImmAttrNameT(name)

> -            c_attr_mod.modAttr.attrValueType = attr_type

> -            c_attr_mod.modAttr.attrValuesNumber = len(values)

> -            c_attr_mod.modAttr.attrValues = marshal_c_array(attr_type, 
> values)

> -            attr_mods.append(c_attr_mod)

> -

> -        rc = saImmOiRtObjectUpdate_2(self.handle, SaNameT(dn), attr_mods)

> -

> -        return rc

> -

> -    def report_admin_operation_result(self, invocation_id, result):

> -        """ Report the result of an administrative operation

> -

> -        Args:

> -            invocation_id (SaInvocationT): Invocation id

> -            result (SaAisErrorT): Result of admin operation

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI admin operation

> -        """

> -        rc = saImmOiAdminOperationResult(self.handle, invocation_id,

> -                                         result)

> -

> -        return rc

> -

> -    def set_error_string(self, ccb_id, error_string):

> -        """ Set the error string

> -        This can only be called from within OI callbacks of a real 
> implementer.

> -

> -        Args:

> -            ccb_id (SaImmOiCcbIdT): CCB id

> -            error_string (str): Error string

> -

> -        Returns:

> -            SaAisErrorT: Return code of OI CCB set error string

> -        """

> -        c_error_string = SaStringT(error_string)

> -        rc = saImmOiCcbSetErrorString(self.handle, ccb_id, c_error_string)

> -

> -        return rc

> -

> -

>   # Keep old user interfaces of OI pyosaf utils

>   @deprecate

>   def initialize(callbacks=None):

> @@ -327,8 +52,8 @@ def initialize(callbacks=None):

>               is not SA_AIS_OK

>       """

>       global _oi_agent

> -    if _oi_agent is None:

> -        _oi_agent = OiAgent()

> +    _oi_agent = OiAgent()

> +

>       rc = _oi_agent.initialize(callbacks=callbacks)

>       if rc != eSaAisErrorT.SA_AIS_OK:

>           raise SafException(rc)

> @@ -342,10 +67,9 @@ def get_selection_object():

>           SaSelectionObjectT: Return code of selection object get

>   

>       Raises:

> -        SafException: If the return code of the corresponding OI API call(s)

> -            is not SA_AIS_OK

> +        SafException: If the OI agent is not initialized

>       """

> -    if _oi_agent is not None:

> +    if _oi_agent is None:

>           # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

>           # calling initialize()

>           raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

> @@ -363,11 +87,16 @@ def create_rt_object(class_name, parent_name, 
> runtime_obj):

>           runtime_obj (ImmObject): Runtime object to create

>   

>       Raises:

> -        SafException: If the return code of the corresponding OI API call(s)

> -            is not SA_AIS_OK

> +        SafException: If the OI agent is not initialized

>       """

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        rc = eSaAisErrorT.SA_AIS_ERR_INIT

> +    else:

> +        rc = _oi_agent.create_runtime_object(class_name, parent_name,

> +                                             runtime_obj)

>   

> -    rc = _oi_agent.create_runtime_object(class_name, parent_name, 
> runtime_obj)

>       if rc != eSaAisErrorT.SA_AIS_OK:

>           raise SafException(rc)

>   

> @@ -380,10 +109,15 @@ def delete_rt_object(dn):

>           dn (str): Runtime object dn

>   

>       Raises:

> -        SafException: If the return code of the corresponding OI API call(s)

> -            is not SA_AIS_OK

> +        SafException: If the OI agent is not initialized

>       """

> -    rc = _oi_agent.delete_runtime_object(dn)

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        rc = eSaAisErrorT.SA_AIS_ERR_INIT

> +    else:

> +        rc = _oi_agent.delete_runtime_object(dn)

> +

>       if rc != eSaAisErrorT.SA_AIS_OK:

>           raise SafException(rc)

>   

> @@ -398,10 +132,15 @@ def update_rt_object(dn, attributes):

>           attributes (dict): Dictionary of attribute modifications

>   

>       Raises:

> -        SafException: If the return code of the corresponding OI API call(s)

> -            is not SA_AIS_OK

> +        SafException: If the OI agent is not initialized

>       """

> -    rc = _oi_agent.update_runtime_object(dn, attributes)

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        rc = eSaAisErrorT.SA_AIS_ERR_INIT

> +    else:

> +        rc = _oi_agent.update_runtime_object(dn, attributes)

> +

>       if rc != eSaAisErrorT.SA_AIS_OK:

>           raise SafException(rc)

>   

> @@ -415,10 +154,15 @@ def report_admin_operation_result(invocation_id, 
> result):

>           result (SaAisErrorT): Result of admin operation

>   

>       Raises:

> -        SafException: If the return code of the corresponding OI API call(s)

> -            is not SA_AIS_OK

> +        SafException: If the OI agent is not initialized

>       """

> -    rc = _oi_agent.report_admin_operation_result(invocation_id, result)

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        rc = eSaAisErrorT.SA_AIS_ERR_INIT

> +    else:

> +        rc = _oi_agent.report_admin_operation_result(invocation_id, result)

> +

>       if rc != eSaAisErrorT.SA_AIS_OK:

>           raise SafException(rc)

>   

> @@ -433,26 +177,20 @@ def set_error_string(ccb_id, error_string):

>           error_string (str): Error string

>   

>       Raises:

> -        SafException: If the return code of the corresponding OI API call(s)

> -            is not SA_AIS_OK

> +        SafException: If the OI agent is not initialized

>       """

> -    rc = _oi_agent.set_error_string(ccb_id, error_string)

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        rc = eSaAisErrorT.SA_AIS_ERR_INIT

> +    else:

> +        rc = _oi_agent.set_error_string(ccb_id, error_string)

> +

>       if rc != eSaAisErrorT.SA_AIS_OK:

>           raise SafException(rc)

>   

>   

> -def get_class_category(class_name):

> -    """ Return the category of the given class

> -

> -    Args:

> -        class_name (str): Class name

> -

> -    Returns:

> -        SaImmClassCategoryT: Class category

> -    """

> -    return immom.get_class_category(class_name)

> -

> -

> +@deprecate

>   def get_parent_name_for_dn(dn):

>       """ Return the parent's dn of the given object's dn

>   

> @@ -461,13 +199,19 @@ def get_parent_name_for_dn(dn):

>   

>       Returns:

>           str: DN of the object's parent

> +

> +    Raises:

> +        SafException: If the OI agent is not initialized

>       """

> -    if ',' in dn:

> -        return dn.split(',', 1)[1]

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

>   

> -    return ""

> +    return _oi_agent.get_parent_name_for_dn(dn)

>   

>   

> +@deprecate

>   def get_object_names_for_class(class_name):

>       """ Return instances of the given class

>   

> @@ -476,28 +220,19 @@ def get_object_names_for_class(class_name):

>   

>       Returns:

>           list: List of object names

> +

> +    Raises:

> +        SafException: If the OI agent is not initialized

>       """

> -    # Marshall the search parameter

> -    c_class_name = c_char_p(class_name)

> -    c_search_param = SaImmSearchParametersT_2()

> -    c_search_param.searchOneAttr.attrName = "SaImmAttrClassName"

> -    c_search_param.searchOneAttr.attrValueType = \

> -        eSaImmValueTypeT.SA_IMM_ATTR_SASTRINGT

> -    c_search_param.searchOneAttr.attrValue = \

> -        cast(pointer(c_class_name), c_void_p)

> -

> -    # Create the search iterator

> -    found_objs = SearchIterator(search_param=c_search_param,

> -                                attribute_names=['SaImmAttrClassName'])

> -    found_objs.init()

> -    # Return the dn's of found objects

> -    object_names = []

> -    for obj in found_objs:

> -        object_names.append(obj.dn)

> -

> -    return object_names

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

> +

> +    return _oi_agent.get_object_names_for_class(class_name)

>   

>   

> +@deprecate

>   def get_class_name_for_dn(dn):

>       """ Return the class name for an instance with the given dn

>   

> @@ -506,14 +241,19 @@ def get_class_name_for_dn(dn):

>   

>       Returns:

>           str: Class name

> +

> +    Raises:

> +        SafException: If the OI agent is not initialized

>       """

> -    obj = immom.get(dn, ["SaImmAttrClassName"])

> -    if not obj:

> -        return None

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

>   

> -    return obj.SaImmAttrClassName

> +    return _oi_agent.get_class_name_for_dn(dn)

>   

>   

> +@deprecate

>   def get_object_no_runtime(dn):

>       """ Return the IMM object with the given dn

>   

> @@ -522,10 +262,19 @@ def get_object_no_runtime(dn):

>   

>       Returns:

>           ImmObject: Imm object

> +

> +    Raises:

> +        SafException: If the OI agent is not initialized

>       """

> -    return immom.get(dn, ['SA_IMM_SEARCH_GET_CONFIG_ATTR'])

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

>   

> +    return _oi_agent.get_object_no_runtime(dn)

>   

> +

> +@deprecate

>   def get_attribute_type(attribute, class_name):

>       """ Return the type of the attribute in the given class

>   

> @@ -535,72 +284,37 @@ def get_attribute_type(attribute, class_name):

>   

>       Returns:

>           str: Attribute type

> -    """

> -    class_desc = immom.class_description_get(class_name)

> -    attr_desc = [attr for attr in class_desc if

> -                 attr.attrName == attribute][0]

> -

> -    return attr_desc.attrValueType

>   

> -

> -def get_rdn_attribute_for_class(class_name):

> -    """ Return the RDN attribute for the given class

> -

> -    Args:

> -        class_name (str): Class name

> -

> -    Returns:

> -        str: RDN of the class

> +    Raises:

> +        SafException: If the OI agent is not initialized

>       """

> -    desc = immom.class_description_get(class_name)

> -

> -    for attr_desc in desc:

> -        if attr_desc.attrFlags & saImm.saImm.SA_IMM_ATTR_RDN:

> -            return attr_desc.attrName

> -

> -    return None

> -

> -

> -def unmarshal_len_array(c_array, length, value_type):

> -    """ Convert C array with a known length to a Python list

> -

> -    Args:

> -        c_array (C array): Array in C

> -        length (int): Length of array

> -        value_type (str): Element type in array

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

>   

> -    Returns:

> -        list: The list converted from c_array

> -    """

> -    if not c_array:

> -        return []

> -    ctype = c_array[0].__class__

> -    if ctype is str:

> -        return unmarshalSaStringTArray(c_array)

> -    val_list = []

> -    i = 0

> -    for ptr in c_array:

> -        if i == length:

> -            break

> -        if not ptr:

> -            break

> -        val = unmarshalSaImmValue(ptr, value_type)

> -        val_list.append(val)

> -        i = i + 1

> -

> -    return val_list

> +    return _oi_agent.get_attribute_type(attribute, class_name)

>   

>   

> +@deprecate

>   def get_available_classes_in_imm():

>       """ Return a list of all available classes in IMM

>   

>       Returns:

>           list: List of available classes

> +

> +    Raises:

> +        SafException: If the OI agent is not initialized

>       """

> -    opensaf_imm = immom.get(OPENSAF_IMM_OBJECT)

> -    return opensaf_imm.opensafImmClassNames

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

>   

> +    return _oi_agent.get_available_classes_in_imm()

>   

> +

> +@deprecate

>   def create_non_existing_imm_object(class_name, parent_name,

>                                      attributes):

>       """ Create an ImmObject instance for an object that has not yet existed

> @@ -613,21 +327,14 @@ def create_non_existing_imm_object(class_name, 
> parent_name,

>   

>       Returns:

>           ImmObject: Imm object

> -    """

> -    rdn_attribute = get_rdn_attribute_for_class(class_name)

> -    rdn_value = attributes[rdn_attribute][0]

> -

> -    if parent_name:

> -        dn = '%s,%s' % (rdn_value, parent_name)

> -    else:

> -        dn = rdn_value

> -

> -    obj = ImmObject(class_name=class_name, dn=dn)

>   

> -    for name, values in attributes.items():

> -        obj.__setattr__(name, values)

> -

> -    obj.__setattr__('SaImmAttrClassName', class_name)

> -    obj.__setattr__('dn', dn)

> +    Raises:

> +        SafException: If the OI agent is not initialized

> +    """

> +    if _oi_agent is None:

> +        # SA_AIS_ERR_INIT is returned if user calls this function without 
> first

> +        # calling initialize()

> +        raise SafException(eSaAisErrorT.SA_AIS_ERR_INIT)

>   

> -    return obj

> +    return _oi_agent.create_non_existing_imm_object(class_name, parent_name,

> +                                                    attributes)

> diff --git a/python/pyosaf/utils/immoi/agent.py 
> b/python/pyosaf/utils/immoi/agent.py

> new file mode 100644

> index 0000000..1e34b4f

> --- /dev/null

> +++ b/python/pyosaf/utils/immoi/agent.py

> @@ -0,0 +1,473 @@

> +############################################################################

> +#

> +# (C) Copyright 2015 The OpenSAF Foundation

> +# (C) Copyright 2017 Ericsson AB. All rights reserved.

> +#

> +# This program is distributed in the hope that it will be useful, but

> +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY

> +# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed

> +# under the GNU Lesser General Public License Version 2.1, February 1999.

> +# The complete license can be accessed from the following location:

> +#  <http://opensource.org/licenses/lgpl-license.php> 
> http://opensource.org/licenses/lgpl-license.php

> +# See the Copying file included with the OpenSAF distribution for full

> +# licensing terms.

> +#

> +# Author(s): Ericsson

> +#

> +############################################################################

> +"""

> +IMM OI common utilities

> +

> +Supported functions:

> +- Set/clear/release implementer for class/object

> +- Create/delete/update runtime object

> +- Get class/object attributes

> +- Get IMM error strings

> +"""

> +from __future__ import print_function

> +from copy import deepcopy

> +from ctypes import c_char_p, c_void_p, cast, pointer

> +

> +from pyosaf.saAis import SaStringT, SaVersionT, SaNameT, SaSelectionObjectT, 
> \

> +    eSaDispatchFlagsT, eSaAisErrorT

> +from pyosaf import saImmOi

> +from pyosaf.saImm import SaImmAttrNameT, SaImmAttrValuesT_2, 
> SaImmClassNameT, \

> +    SaImmSearchParametersT_2, eSaImmValueTypeT, SaImmAttrModificationT_2, \

> +    eSaImmAttrModificationTypeT

> +from pyosaf.saImmOi import SaImmOiHandleT

> +from pyosaf.utils import log_err, bad_handle_retry, decorate, \

> +    initialize_decorate

> +from pyosaf.utils.immom.object import ImmObject

> +from pyosaf.utils.immom.ccb import marshal_c_array

> +from pyosaf.utils.immom.iterator import SearchIterator

> +from pyosaf.utils.immom.agent import OmAgent

> +from pyosaf.utils.immom.accessor import Accessor

> +

> +

> +OPENSAF_IMM_OBJECT = "opensafImm=opensafImm,safApp=safImmService"

> +

> +

> +# Decorate pure saImmOi* API's with error-handling retry and exception 
> raising

> +saImmOiInitialize_2 = initialize_decorate(saImmOi.saImmOiInitialize_2)

> +saImmOiSelectionObjectGet = decorate(saImmOi.saImmOiSelectionObjectGet)

> +saImmOiDispatch = decorate(saImmOi.saImmOiDispatch)

> +saImmOiFinalize = decorate(saImmOi.saImmOiFinalize)

> +saImmOiImplementerSet = decorate(saImmOi.saImmOiImplementerSet)

> +saImmOiImplementerClear = decorate(saImmOi.saImmOiImplementerClear)

> +saImmOiClassImplementerSet = decorate(saImmOi.saImmOiClassImplementerSet)

> +saImmOiClassImplementerRelease = \

> +    decorate(saImmOi.saImmOiClassImplementerRelease)

> +saImmOiObjectImplementerSet = decorate(saImmOi.saImmOiObjectImplementerSet)

> +saImmOiObjectImplementerRelease = \

> +    decorate(saImmOi.saImmOiObjectImplementerRelease)

> +saImmOiRtObjectCreate_2 = decorate(saImmOi.saImmOiRtObjectCreate_2)

> +saImmOiRtObjectDelete = decorate(saImmOi.saImmOiRtObjectDelete)

> +saImmOiRtObjectUpdate_2 = decorate(saImmOi.saImmOiRtObjectUpdate_2)

> +saImmOiAdminOperationResult = decorate(saImmOi.saImmOiAdminOperationResult)

> +saImmOiAdminOperationResult_o2 = \

> +    decorate(saImmOi.saImmOiAdminOperationResult_o2)

> +saImmOiAugmentCcbInitialize = decorate(saImmOi.saImmOiAugmentCcbInitialize)

> +saImmOiCcbSetErrorString = decorate(saImmOi.saImmOiCcbSetErrorString)

> +

> +

> +class OiAgent(object):

> +    """ This class acts as a high-level OI agent, providing OI functions to

> +    the users as a higher level, and relieving the users of the need to 
> manage

> +    the life cycle of the OI agent and providing general interface for

> +    Implementer or Applier used

> +    """

> +    def __init__(self, version=None):

> +        """ Constructor for OiAgent class

> +

> +        Args:

> +            version (SaVersionT): OI API version

> +        """

> +        self.handle = None

> +        self.init_version = version if version is not None \

> +            else SaVersionT('A', 2, 15)

> +        self.version = None

> +        self.selection_object = None

> +        self.callbacks = None

> +        self.imm_om = None

> +        self.accessor = None

> +

> +    def _fetch_sel_obj(self):

> +        """ Obtain a selection object (OS file descriptor)

> +

> +        Returns:

> +            SaAisErrorT: Return code of the saImmOiSelectionObjectGet() API

> +        """

> +        rc = saImmOiSelectionObjectGet(self.handle, self.selection_object)

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiSelectionObjectGet FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

> +

> +        return rc

> +

> +    def initialize(self, callbacks=None):

> +        """ Initialize the IMM OI agent

> +

> +        Args:

> +            callbacks (SaImmOiCallbacksT_2): OI callbacks to register with 
> IMM

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI initialize

> +        """

> +        self.imm_om = OmAgent(self.init_version)

> +        rc = self.imm_om.init()

> +

> +        if rc == eSaAisErrorT.SA_AIS_OK:

> +            if not self.accessor:

> +                self.accessor = Accessor(self.init_version)

> +                rc = self.accessor.init()

> +                if rc != eSaAisErrorT.SA_AIS_OK:

> +                    log_err("saImmOmAccessorInitialize FAILED - %s" %

> +                            eSaAisErrorT.whatis(rc))

> +                    return rc

> +

> +            self.handle = SaImmOiHandleT()

> +            self.selection_object = SaSelectionObjectT()

> +            if callbacks is not None:

> +                self.callbacks = callbacks

> +            self.version = deepcopy(self.init_version)

> +            rc = saImmOiInitialize_2(self.handle, self.callbacks,

> +                                     self.version)

> +            if rc == eSaAisErrorT.SA_AIS_OK:

> +                rc = self._fetch_sel_obj()

> +                if rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:

> +                    rc = self.re_initialize()

> +            else:

> +                log_err("saImmOiInitialize_2 FAILED - %s" %

> +                        eSaAisErrorT.whatis(rc))

> +        else:

> +            log_err("saImmOmInitialize FAILED - %s" % 
> eSaAisErrorT.whatis(rc))

> +

> +        return rc

> +

> +    @bad_handle_retry

> +    def re_initialize(self):

> +        """ Re-initialize the IMM OI agent

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI initialize

> +        """

> +        self.finalize()

> +        rc = self.initialize()

> +

> +        return rc

> +

> +    def finalize(self):

> +        """ Finalize IMM OI agent handle

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI finalize

> +        """

> +        rc = eSaAisErrorT.SA_AIS_OK

> +        if self.handle is not None:

> +            rc = saImmOiFinalize(self.handle)

> +            if rc != eSaAisErrorT.SA_AIS_OK:

> +                log_err("saImmOiFinalize FAILED - %s" %

> +                        eSaAisErrorT.whatis(rc))

> +

> +            if rc == eSaAisErrorT.SA_AIS_OK \

> +                    or rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:

> +                # If the Finalize() call returned BAD_HANDLE, the handle 
> should

> +                # already become stale and invalid, so we reset it anyway.

> +                self.handle = None

> +        return rc

> +

> +    def get_selection_object(self):

> +        """ Return the selection object associating with the OI handle

> +

> +        Returns:

> +            SaSelectionObjectT: Selection object associated with the OI 
> handle

> +        """

> +        return self.selection_object

> +

> +    def dispatch(self, flags=eSaDispatchFlagsT.SA_DISPATCH_ALL):

> +        """ Dispatch all queued callbacks

> +

> +        Args:

> +            flags (eSaDispatchFlagsT): Flags specifying dispatch mode

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI dispatch

> +        """

> +        rc = saImmOiDispatch(self.handle, flags)

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiDispatch FAILED - %s" % eSaAisErrorT.whatis(rc))

> +        return rc

> +

> +    def create_runtime_object(self, class_name, parent_name, runtime_obj):

> +        """ Create a runtime object

> +

> +        Args:

> +            class_name (str): Class name

> +            parent_name (str): Parent name

> +            runtime_obj (ImmObject): Runtime object to create

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI create runtime object

> +        """

> +        # Marshall parameters

> +        c_class_name = SaImmClassNameT(class_name)

> +        if parent_name:

> +            c_parent_name = SaNameT(parent_name)

> +        else:

> +            c_parent_name = None

> +

> +        c_attr_values = []

> +

> +        for name, (c_attr_type, values) in runtime_obj.attrs.items():

> +            if values is None:

> +                values = []

> +            elif values == [None]:

> +                values = []

> +

> +            # Make sure all values are in lists

> +            if not isinstance(values, list):

> +                values = [values]

> +

> +            # Create the values struct

> +            c_attr = SaImmAttrValuesT_2()

> +            c_attr.attrName = SaImmAttrNameT(name)

> +            c_attr.attrValueType = c_attr_type

> +            c_attr.attrValuesNumber = len(values)

> +

> +            if not values:

> +                c_attr.attrValues = None

> +            else:

> +                c_attr.attrValues = marshal_c_array(c_attr_type, values)

> +

> +            c_attr_values.append(c_attr)

> +

> +        rc = saImmOiRtObjectCreate_2(self.handle, c_class_name,

> +                                     c_parent_name, c_attr_values)

> +

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiRtObjectCreate_2 FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

> +        return rc

> +

> +    def delete_runtime_object(self, dn):

> +        """ Delete a runtime object

> +

> +        Args:

> +            dn (str): Runtime object dn

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI delete runtime object

> +        """

> +        # Marshall the parameter

> +        c_dn = SaNameT(dn)

> +        rc = saImmOiRtObjectDelete(self.handle, c_dn)

> +

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiRtObjectDelete FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

> +        return rc

> +

> +    def update_runtime_object(self, dn, attributes):

> +        """ Update the specified object with the requested attribute

> +        modifications

> +

> +        Args:

> +            dn (str): Object dn

> +            attributes (dict): Dictionary of attribute modifications

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI update runtime object

> +        """

> +        # Get the class name for the object

> +        class_name = self.get_class_name_for_dn(dn)

> +

> +        # Create and marshall attribute modifications

> +        attr_mods = []

> +

> +        for name, values in attributes.items():

> +            if values is None:

> +                print("WARNING: Received no values for %s in %s" % (name, 
> dn))

> +                continue

> +            if not isinstance(values, list):

> +                values = [values]

> +

> +            attr_type = self.get_attribute_type(name, class_name)

> +            c_attr_mod = SaImmAttrModificationT_2()

> +            c_attr_mod.modType = \

> +                eSaImmAttrModificationTypeT.SA_IMM_ATTR_VALUES_REPLACE

> +            c_attr_mod.modAttr = SaImmAttrValuesT_2()

> +            c_attr_mod.modAttr.attrName = SaImmAttrNameT(name)

> +            c_attr_mod.modAttr.attrValueType = attr_type

> +            c_attr_mod.modAttr.attrValuesNumber = len(values)

> +            c_attr_mod.modAttr.attrValues = marshal_c_array(attr_type, 
> values)

> +            attr_mods.append(c_attr_mod)

> +

> +        rc = saImmOiRtObjectUpdate_2(self.handle, SaNameT(dn), attr_mods)

> +

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiRtObjectUpdate_2 FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

> +        return rc

> +

> +    def report_admin_operation_result(self, invocation_id, result):

> +        """ Report the result of an administrative operation

> +

> +        Args:

> +            invocation_id (SaInvocationT): Invocation id

> +            result (SaAisErrorT): Result of admin operation

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI admin operation

> +        """

> +        rc = saImmOiAdminOperationResult(self.handle, invocation_id, result)

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiAdminOperationResult FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

> +        return rc

> +

> +    def set_error_string(self, ccb_id, error_string):

> +        """ Set the error string

> +        This can only be called from within OI callbacks of a real 
> implementer.

> +

> +        Args:

> +            ccb_id (SaImmOiCcbIdT): CCB id

> +            error_string (str): Error string

> +

> +        Returns:

> +            SaAisErrorT: Return code of OI CCB set error string

> +        """

> +        c_error_string = SaStringT(error_string)

> +        rc = saImmOiCcbSetErrorString(self.handle, ccb_id, c_error_string)

> +

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiCcbSetErrorString FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

> +        return rc

> +

> +    def get_attribute_type(self, attribute, class_name):

> +        """ Return the type of the attribute in the given class

> +

> +        Args:

> +            attribute (str): Attribute name

> +            class_name (str): Class name

> +

> +        Returns:

> +            str: Attribute type

> +        """

> +        _, class_desc = self.imm_om.get_class_description(class_name)

> +        attr_desc = [attr for attr in class_desc if

> +                     attr.attrName == attribute][0]

> +

> +        return attr_desc.attrValueType

> +

> +    @staticmethod

> +    def get_parent_name_for_dn(dn):

> +        """ Return the parent's dn of the given object's dn

> +

> +        Args:

> +            dn (str): Object dn

> +

> +        Returns:

> +            str: DN of the object's parent

> +        """

> +        if ',' in dn:

> +            return dn.split(',', 1)[1]

> +

> +        return ""

> +

> +    @staticmethod

> +    def get_object_names_for_class(class_name):

> +        """ Return instances of the given class

> +

> +        Args:

> +            class_name (str): Class name

> +

> +        Returns:

> +            list: List of object names

> +        """

> +        # Marshall the search parameter

> +        c_class_name = c_char_p(class_name)

> +        c_search_param = SaImmSearchParametersT_2()

> +        c_search_param.searchOneAttr.attrName = "SaImmAttrClassName"

> +        c_search_param.searchOneAttr.attrValueType = \

> +            eSaImmValueTypeT.SA_IMM_ATTR_SASTRINGT

> +        c_search_param.searchOneAttr.attrValue = \

> +            cast(pointer(c_class_name), c_void_p)

> +

> +        # Create the search iterator

> +        found_objs = SearchIterator(search_param=c_search_param,

> +                                    attribute_names=['SaImmAttrClassName'])

> +        found_objs.init()

> +        # Return the dn's of found objects

> +        object_names = []

> +        for obj in found_objs:

> +            object_names.append(obj.dn)

> +

> +        return object_names

> +

> +    def get_class_name_for_dn(self, dn):

> +        """ Return the class name for an instance with the given dn

> +

> +        Args:

> +            dn (str): Object dn

> +

> +        Returns:

> +            str: Class name

> +        """

> +        _, obj = self.accessor.get(dn, ["SaImmAttrClassName"])

> +        if not obj:

> +            return None

> +

> +        return obj.SaImmAttrClassName

> +

> +    def get_object_no_runtime(self, dn):

> +        """ Return the IMM object with the given dn

> +

> +        Args:

> +            dn (str): Object dn

> +

> +        Returns:

> +            ImmObject: Imm object

> +        """

> +        _, obj = self.accessor.get(dn, ['SA_IMM_SEARCH_GET_CONFIG_ATTR'])

> +        return obj

> +

> +    def get_available_classes_in_imm(self):

> +        """ Return a list of all available classes in IMM

> +

> +        Returns:

> +            list: List of available classes

> +        """

> +        _, opensaf_imm = self.accessor.get(OPENSAF_IMM_OBJECT)

> +        return opensaf_imm.opensafImmClassNames

> +

> +    def create_non_existing_imm_object(self, class_name, parent_name,

> +                                       attributes):

> +        """ Create an ImmObject instance for an object that has not yet 
> existed

> +        in IMM

> +

> +        Args:

> +            class_name (str): Class name

> +            parent_name (str): Parent name

> +            attributes (dict): Dictionary of class attributes

> +

> +        Returns:

> +            ImmObject: Imm object

> +        """

> +        rdn_attribute = self.imm_om.get_rdn_attribute_for_class(class_name)

> +        rdn_value = attributes[rdn_attribute][0]

> +

> +        if parent_name:

> +            dn = '%s,%s' % (rdn_value, parent_name)

> +        else:

> +            dn = rdn_value

> +

> +        obj = ImmObject(class_name=class_name, dn=dn)

> +

> +        for name, values in attributes.items():

> +            obj.__setattr__(name, values)

> +

> +        obj.__setattr__('SaImmAttrClassName', class_name)

> +        obj.__setattr__('dn', dn)

> +

> +        return obj

> diff --git a/python/pyosaf/utils/immoi/implementer.py 
> b/python/pyosaf/utils/immoi/implementer.py

> index da1d945..f8f66cd 100755

> --- a/python/pyosaf/utils/immoi/implementer.py

> +++ b/python/pyosaf/utils/immoi/implementer.py

> @@ -21,12 +21,13 @@ from __future__ import print_function

>   import select

>   import itertools

>   

> -from pyosaf.saAis import eSaAisErrorT, unmarshalNullArray

> +from pyosaf.saAis import eSaAisErrorT, unmarshalNullArray, \

> +    unmarshalSaStringTArray

>   from pyosaf import saImm, saImmOi

>   from pyosaf.saImm import eSaImmValueTypeT, eSaImmAttrModificationTypeT, \

> -    eSaImmClassCategoryT, SaImmClassNameT

> +    eSaImmClassCategoryT, SaImmClassNameT, unmarshalSaImmValue

>   from pyosaf.saImmOi import SaImmOiImplementerNameT

> -from pyosaf.utils import immom, immoi, SafException, decorate, 
> bad_handle_retry

> +from pyosaf.utils import SafException, decorate, bad_handle_retry, log_err

>   from pyosaf.utils.immoi import OiAgent

>   from pyosaf.utils.immom.object import ImmObject

>   

> @@ -35,9 +36,6 @@ saImmOiClassImplementerSet = 
> decorate(saImmOi.saImmOiClassImplementerSet)

>   saImmOiImplementerSet = decorate(saImmOi.saImmOiImplementerSet)

>   

>   

> -implementer_instance = None

> -

> -

>   class AdminOperationParameter(object):

>       """ This class represents an admin operation parameter """

>       def __init__(self, name, param_type, value):

> @@ -101,12 +99,13 @@ class _ContainmentConstraint(object):

>           self.upper = upper

>   

>   

> -class Constraints(object):

> +class Constraints(OiAgent):

>       """ Class defining constraints for changes to the instances implemented 
> by

>       the OI

>       """

>       def __init__(self):

>           """ Create an empty Constraints instance """

> +        super(Constraints, self).__init__()

>           self.containments = {}

>           self.cardinality = {}

>   

> @@ -153,7 +152,7 @@ class Constraints(object):

>                   if ',' not in child.dn:

>                       continue

>   

> -                if immoi.get_parent_name_for_dn(child.dn) == _parent_name \

> +                if self.get_parent_name_for_dn(child.dn) == _parent_name \

>                           and child.class_name == _class_name:

>                       _current_children.append(child)

>   

> @@ -170,10 +169,10 @@ class Constraints(object):

>               return False

>   

>           # Validate containments affected by create or delete

> -        deleted_objs = [immoi.get_object_no_runtime(dn) for dn in deleted]

> +        deleted_objs = [self.get_object_no_runtime(dn) for dn in deleted]

>   

>           for obj in itertools.chain(created, deleted_objs):

> -            parent_name = immoi.get_parent_name_for_dn(obj.dn)

> +            parent_name = self.get_parent_name_for_dn(obj.dn)

>   

>               # Handle the case where there is no parent

>               if not parent_name:

> @@ -196,7 +195,7 @@ class Constraints(object):

>               if parent_obj:

>                   parent_class = parent_obj[0].class_name

>               else:

> -                parent_class = immoi.get_class_name_for_dn(dn=parent_name)

> +                parent_class = self.get_class_name_for_dn(dn=parent_name)

>   

>               # Ignore children where no constraint is defined for the child 
> or

>               # the parent

> @@ -244,10 +243,10 @@ class Implementer(OiAgent):

>       def __init__(self, class_names=None, name="wrapper", on_create=None,

>                    on_delete=None, on_modify=None, on_validate=None,

>                    on_apply=None, on_runtime_values_get=None,

> -                 admin_operations=None, constraints=None):

> +                 admin_operations=None, constraints=None, version=None):

>           """ Create an Implementer instance """

>           # Initialize OI agent

> -        super(Implementer, self).__init__()

> +        super(Implementer, self).__init__(version=version)

>   

>           self.class_names = class_names

>           self.name = name

> @@ -263,14 +262,43 @@ class Implementer(OiAgent):

>           self.ccbs = {}

>           self.implemented_names = []

>   

> -        global implementer_instance

> -        implementer_instance = self

> -

>           # Register OI callbacks

>           self._register_callbacks()

>   

>           # Initialize OI API and register as implementer for the classes

> -        self._register()

> +        rc = self._register()

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            raise Exception("ERROR: Can't register a implementer")

> +

> +    @staticmethod

> +    def unmarshal_len_array(c_array, length, value_type):

> +        """ Convert C array with a known length to a Python list

> +

> +        Args:

> +            c_array (C array): Array in C

> +            length (int): Length of array

> +            value_type (str): Element type in array

> +

> +        Returns:

> +            list: The list converted from c_array

> +        """

> +        if not c_array:

> +            return []

> +        ctype = c_array[0].__class__

> +        if ctype is str:

> +            return unmarshalSaStringTArray(c_array)

> +        val_list = []

> +        i = 0

> +        for ptr in c_array:

> +            if i == length:

> +                break

> +            if not ptr:

> +                break

> +            val = unmarshalSaImmValue(ptr, value_type)

> +            val_list.append(val)

> +            i = i + 1

> +

> +        return val_list

>   

>       def _register_callbacks(self):

>           """ Register OI callbacks """

> @@ -297,8 +325,7 @@ class Implementer(OiAgent):

>               saImmOi.SaImmOiAdminOperationCallbackT_2(

>                   self._admin_operation_callback)

>   

> -    @staticmethod

> -    def _admin_operation_callback(oi_handle, c_invocation_id, c_name,

> +    def _admin_operation_callback(self, oi_handle, c_invocation_id, c_name,

>                                     c_operation_id, c_params):

>           """ Callback for administrative operations

>   

> @@ -329,12 +356,11 @@ class Implementer(OiAgent):

>               params.append(parameter)

>   

>           # Invoke the operation

> -        result = implementer_instance.admin_operation(operation_id, name,

> -                                                      params)

> +        result = self.admin_operation(operation_id, name, params)

>   

>           # Report the result

>           try:

> -            immoi.report_admin_operation_result(invocation_id, result)

> +            self.report_admin_operation_result(invocation_id, result)

>           except SafException as err:

>               print("ERROR: Failed to report that %s::%s returned %s (%s)" %

>                     (name, invocation_id, result, err.msg))

> @@ -358,11 +384,10 @@ class Implementer(OiAgent):

>           """

>           all_instances = []

>   

> -        for class_name in implementer_instance.class_names:

> -            dns = immoi.get_object_names_for_class(class_name)

> +        for class_name in self.class_names:

> +            dns = self.get_object_names_for_class(class_name)

>               for dn in dns:

> -                dn_in_str = str(dn.value)

> -                obj = immoi.get_object_no_runtime(dn_in_str)

> +                obj = self.get_object_no_runtime(dn)

>                   all_instances.append(obj)

>   

>           updated = self.completed_ccbs[ccb_id]['updated']

> @@ -374,8 +399,7 @@ class Implementer(OiAgent):

>           del self.completed_ccbs[ccb_id]

>   

>           # Tell the implementer to apply the changes

> -        return implementer_instance.on_apply(all_instances, updated,

> -                                             created, deleted)

> +        return self.on_apply(all_instances, updated, created, deleted)

>   

>       def _attr_update_callback(self, oi_handle, c_name, c_attr_names):

>           """ Callback for attribute update operation

> @@ -395,15 +419,13 @@ class Implementer(OiAgent):

>           attr_names = unmarshalNullArray(c_attr_names)

>   

>           # Get the class of the object

> -        class_name = immoi.get_class_name_for_dn(dn=name)

> +        class_name = self.get_class_name_for_dn(dn=name)

>   

>           # Get the values from the user and report back

>           attributes = {}

>   

>           for attr_name in attr_names:

> -            values = implementer_instance.on_runtime_values_get(name,

> -                                                                class_name,

> -                                                                attr_name)

> +            values = self.on_runtime_values_get(name, class_name, attr_name)

>               if values is None:

>                   return eSaAisErrorT.SA_AIS_ERR_UNAVAILABLE

>               if not isinstance(values, list):

> @@ -442,7 +464,7 @@ class Implementer(OiAgent):

>           self.ccbs[ccb_id].append({'type': 'DELETE', 'dn': name})

>   

>           # Tell the implementer about the operation

> -        return implementer_instance.on_delete_added(name)

> +        return self.on_delete_added(name)

>   

>       def _ccb_modify_callback(self, oi_handle, ccb_id, c_name,

>                                c_attr_modification):

> @@ -470,7 +492,7 @@ class Implementer(OiAgent):

>               attr_name = attr.modAttr.attrName

>               attr_type = attr.modAttr.attrValueType

>               mod_type = attr.modType

> -            attr_values = immoi.unmarshal_len_array(

> +            attr_values = self.unmarshal_len_array(

>                   attr.modAttr.attrValues, attr.modAttr.attrValuesNumber,

>                   attr.modAttr.attrValueType)

>               attribute_modifications.append({'attribute': attr_name,

> @@ -479,8 +501,7 @@ class Implementer(OiAgent):

>                                               'values': attr_values})

>   

>               # Tell the implementer about the modification

> -            result = implementer_instance.on_modify_added(attr_name, 
> mod_type,

> -                                                          attr_values)

> +            result = self.on_modify_added(attr_name, mod_type, attr_values)

>               if result != eSaAisErrorT.SA_AIS_OK:

>                   implementer_objection = result

>   

> @@ -524,16 +545,15 @@ class Implementer(OiAgent):

>               attr_type = attr.attrValueType

>               nr_values = attr.attrValuesNumber

>   

> -            attr_values = immoi.unmarshal_len_array(attr.attrValues,

> -                                                    nr_values,

> -                                                    attr_type)

> +            attr_values = self.unmarshal_len_array(attr.attrValues,

> +                                                   nr_values, attr_type)

>               if attr_values:

>                   attributes[attr_name] = attr_values

>               else:

>                   attributes[attr_name] = None

>   

>           # Fill in any missing attributes

> -        description = immom.class_description_get(class_name)

> +        _, description = self.imm_om.get_class_description(class_name)

>   

>           for attribute in description:

>               if attribute.attrName not in attributes:

> @@ -550,10 +570,10 @@ class Implementer(OiAgent):

>                                     'attributes': attributes})

>   

>           # Tell the implementer about the operation

> -        obj = immoi.create_non_existing_imm_object(class_name, parent,

> -                                                   attributes)

> +        obj = self.create_non_existing_imm_object(class_name, parent,

> +                                                  attributes)

>   

> -        return implementer_instance.on_create_added(class_name, parent, obj)

> +        return self.on_create_added(class_name, parent, obj)

>   

>       def _ccb_completed_callback(self, oi_handle, ccb_id):

>           """ Callback for completed CCB

> @@ -581,8 +601,7 @@ class Implementer(OiAgent):

>                                          'updated': updated}

>   

>           # Perform validation on the full transaction

> -        return implementer_instance.validate(ccb_id, instances, updated,

> -                                             created, deleted)

> +        return self.validate(ccb_id, instances, updated, created, deleted)

>   

>       def _collect_full_transaction(self, ccb_id):

>           """ Go through a completed CCB and summarize the full transaction as

> @@ -605,11 +624,10 @@ class Implementer(OiAgent):

>           updated = []

>   

>           # Go through current instances

> -        for class_name in implementer_instance.class_names:

> -            dns = immoi.get_object_names_for_class(class_name)

> +        for class_name in self.class_names:

> +            dns = self.get_object_names_for_class(class_name)

>               for dn in dns:

> -                dn_in_str = str(dn.value)

> -                obj = immoi.get_object_no_runtime(dn_in_str)

> +                obj = self.get_object_no_runtime(dn)

>                   all_objects_now.append(obj)

>   

>           # Collect proposed state by applying changes on current state

> @@ -621,7 +639,7 @@ class Implementer(OiAgent):

>                   parent = operation['parent']

>                   class_name = operation['className']

>                   attributes = operation['attributes']

> -                rdn_attr = immoi.get_rdn_attribute_for_class(

> +                rdn_attr = self.imm_om.get_rdn_attribute_for_class(

>                       class_name=class_name)

>                   rdn_value = attributes[rdn_attr][0]

>   

> @@ -630,7 +648,7 @@ class Implementer(OiAgent):

>                   else:

>                       dn = rdn_value

>   

> -                instance = immoi.create_non_existing_imm_object(

> +                instance = self.create_non_existing_imm_object(

>                       class_name, parent, attributes)

>                   created.append(instance)

>                   deleted = [obj for obj in deleted if obj.dn != dn]

> @@ -725,6 +743,9 @@ class Implementer(OiAgent):

>           rc = saImmOiClassImplementerSet(self.handle, c_class_name)

>           if rc == eSaAisErrorT.SA_AIS_OK:

>               self.implemented_names.append(class_name)

> +        else:

> +            log_err("saImmOiClassImplementerSet FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

>           return rc

>   

>       def set_constraints(self, constraints):

> @@ -862,7 +883,7 @@ class Implementer(OiAgent):

>               # Let the user code validate the CCB (if configured)

>               self.on_validate(instances, updated, created, deleted)

>           except SafException as err:

> -            immoi.set_error_string(ccb_id, err.msg)

> +            self.set_error_string(ccb_id, err.msg)

>               return err.value

>           except Exception:

>               return eSaAisErrorT.SA_AIS_ERR_FAILED_OPERATION

> @@ -887,7 +908,7 @@ class Implementer(OiAgent):

>               SaAisErrorT: Return code of admin operation

>           """

>           # Get the class name

> -        class_name = immoi.get_class_name_for_dn(object_name)

> +        class_name = self.get_class_name_for_dn(object_name)

>   

>           # Find and execute a matching admin operation

>           if self.admin_operations:

> @@ -928,13 +949,13 @@ class Implementer(OiAgent):

>               SaAisErrorT: Return code of Implementer register

>           """

>           # Initialize the OI API

> -        rc = self.initialize()

> +        rc = self.re_initialize()

>   

>           # Ensure that all classes are configuration classes

>           runtime_classes = None

>           if self.class_names is not None:

>               runtime_classes = [item for item in self.class_names

> -                               if immoi.get_class_category(item) ==

> +                               if self.imm_om.get_class_category(item) ==

>                                  eSaImmClassCategoryT.SA_IMM_CLASS_RUNTIME]

>           if runtime_classes:

>               raise Exception("ERROR: Can't be an applier for runtime "

> @@ -944,7 +965,7 @@ class Implementer(OiAgent):

>           if rc == eSaAisErrorT.SA_AIS_OK:

>               rc = self._register_implementer(self.name)

>   

> -        available_classes = immoi.get_available_classes_in_imm()

> +        available_classes = self.get_available_classes_in_imm()

>   

>           if rc == eSaAisErrorT.SA_AIS_OK:

>               if self.class_names is not None:

> @@ -969,6 +990,10 @@ class Implementer(OiAgent):

>           """

>           implementer_name = SaImmOiImplementerNameT(oi_name)

>           rc = saImmOiImplementerSet(self.handle, implementer_name)

> +

> +        if rc != eSaAisErrorT.SA_AIS_OK:

> +            log_err("saImmOiClassImplementerSet FAILED - %s" %

> +                    eSaAisErrorT.whatis(rc))

>           return rc

>   

>       def update_runtime_attributes(self, dn, attributes):

> @@ -995,7 +1020,7 @@ class Implementer(OiAgent):

>               SaAisErrorT: Return code of implementer object create

>           """

>           # Get the parent name for the object

> -        parent_name = immoi.get_parent_name_for_dn(obj.dn)

> +        parent_name = self.get_parent_name_for_dn(obj.dn)

>           class_name = obj.class_name

>   

>           # Create the object

> @@ -1062,11 +1087,11 @@ class Applier(Implementer):

>               SaAisErrorT: Return code of applier register

>           """

>           # Initialize the OI API

> -        rc = self.initialize()

> +        rc = self.re_initialize()

>   

>           # Ensure that all classes are configuration classes

>           runtime_classes = [item for item in self.class_names

> -                           if immoi.get_class_category(item) ==

> +                           if self.imm_om.get_class_category(item) ==

>                              eSaImmClassCategoryT.SA_IMM_CLASS_RUNTIME]

>           if runtime_classes:

>               raise Exception("ERROR: Can't be an applier for runtime classes 
> %s"

> @@ -1076,7 +1101,7 @@ class Applier(Implementer):

>               rc = self._register_applier(self.name)

>   

>           # Register as applier for each class

> -        available_classes = immoi.get_available_classes_in_imm()

> +        available_classes = self.get_available_classes_in_imm()

>   

>           for class_name in self.class_names:

>               if class_name in available_classes:

> diff --git a/python/pyosaf/utils/immom/__init__.py 
> b/python/pyosaf/utils/immom/__init__.py

> index 57a9692..5706074 100644

> --- a/python/pyosaf/utils/immom/__init__.py

> +++ b/python/pyosaf/utils/immom/__init__.py

> @@ -21,7 +21,7 @@ from pyosaf.saAis import eSaAisErrorT

>   from pyosaf.utils import deprecate, SafException

>   from pyosaf.utils.immom import agent

>   from pyosaf.utils.immom.object import ImmObject

> -from pyosaf.utils.immom.accessor import ImmOmAccessor

> +from pyosaf.utils.immom.accessor import Accessor

>   

>   

>   # Decorate pure saImmOm* API's with error-handling retry and exception 
> raising

> @@ -70,7 +70,7 @@ def initialize():

>           SafException: If any IMM OM API call did not return SA_AIS_OK

>       """

>       global _om_agent

> -    _om_agent = agent.ImmOmAgent()

> +    _om_agent = agent.OmAgent()

>   

>       # Initialize IMM OM handle and return the API return code

>       rc = _om_agent.init()

> @@ -93,7 +93,7 @@ def get(object_name, attr_name_list=None, class_name=None):

>       Raises:

>           SafException: If any IMM OM API call did not return SA_AIS_OK

>       """

> -    _accessor = ImmOmAccessor()

> +    _accessor = Accessor()

>       _accessor.init()

>       rc, imm_object = _accessor.get(object_name, attr_name_list, class_name)

>   

> @@ -173,6 +173,7 @@ def get_rdn_attribute_for_class(class_name):

>       return _om_agent.get_rdn_attribute_for_class(class_name)

>   

>   

> +@deprecate

>   def get_class_category(class_name):

>       """ Return the category of the given class

>   

> diff --git a/python/pyosaf/utils/immom/accessor.py 
> b/python/pyosaf/utils/immom/accessor.py

> index aac0f6d..b411387 100644

> --- a/python/pyosaf/utils/immom/accessor.py

> +++ b/python/pyosaf/utils/immom/accessor.py

> @@ -28,23 +28,23 @@ from pyosaf.utils.immom import agent

>   from pyosaf.utils.immom.object import ImmObject

>   

>   

> -class ImmOmAccessor(agent.ImmOmAgentManager):

> +class Accessor(agent.OmAgentManager):

>       """ This class provides functions of the ImmOm Accessor interface """

>       def __init__(self, version=None):

> -        """ Constructor for ImmOmAccessor class

> +        """ Constructor for Accessor class

>   

>           Args:

>               version (SaVersionT): IMM OM version

>           """

> -        super(ImmOmAccessor, self).__init__(version)

> +        super(Accessor, self).__init__(version)

>           self.accessor_handle = None

>   

>       def __enter__(self):

> -        """ Enter method for ImmOmAccessor class """

> +        """ Enter method for Accessor class """

>           return self

>   

>       def __exit__(self, exception_type, exception_value, traceback):

> -        """ Exit method for ImmOmAccessor class

> +        """ Exit method for Accessor class

>   

>           Finalize the accessor handle and the IMM OM agent handle

>           """

> @@ -56,7 +56,7 @@ class ImmOmAccessor(agent.ImmOmAgentManager):

>               self.handle = None

>   

>       def __del__(self):

> -        """ Destructor for ImmOmAccessor class

> +        """ Destructor for Accessor class

>   

>           Finalize the accessor handle and the IMM OM agent handle

>           """

> @@ -115,10 +115,8 @@ class ImmOmAccessor(agent.ImmOmAgentManager):

>           rc = agent.saImmOmAccessorGet_2(self.accessor_handle,

>                                           SaNameT(object_name),

>                                           attr_names, attributes)

> -        if rc != eSaAisErrorT.SA_AIS_OK:

> -            log_err("saImmOmAccessorGet_2 FAILED - %s" %

> -                    eSaAisErrorT.whatis(rc))

> -        else:

> +

> +        if rc == eSaAisErrorT.SA_AIS_OK:

>               attrs = {}

>               attr_list = unmarshalNullArray(attributes)

>               for attr in attr_list:

> @@ -130,6 +128,17 @@ class ImmOmAccessor(agent.ImmOmAgentManager):

>                                            for val in attr_range]]

>               if 'SaImmAttrClassName' not in attrs and class_name:

>                   attrs['SaImmAttrClassName'] = class_name

> -            imm_obj = ImmObject(object_name, attrs)

> +            imm_obj = ImmObject(dn=object_name, attributes=attrs)

> +

> +        if rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:

> +            init_rc = self.init()

> +            # If the re-initialization of agent handle succeeds, we still 
> need

> +            # to return BAD_HANDLE to the users, so that they would re-try 
> the

> +            # failed operation. Otherwise, the true error code is returned

> +            # to the user to decide further actions.

> +            if init_rc != eSaAisErrorT.SA_AIS_OK:

> +                log_err("saImmOmAccessorGet_2 FAILED - %s" %

> +                        eSaAisErrorT.whatis(rc))

> +                rc = init_rc

>   

>           return rc, imm_obj

> diff --git a/python/pyosaf/utils/immom/agent.py 
> b/python/pyosaf/utils/immom/agent.py

> index b813055..a313aea 100644

> --- a/python/pyosaf/utils/immom/agent.py

> +++ b/python/pyosaf/utils/immom/agent.py

> @@ -64,10 +64,10 @@ saImmOmAdminOperationContinuationClear = \

>       decorate(saImmOm.saImmOmAdminOperationContinuationClear)

>   

>   

> -class ImmOmAgentManager(object):

> +class OmAgentManager(object):

>       """ This class manages the life cycle of an IMM OM agent """

>       def __init__(self, version=None):

> -        """ Constructor for ImmOmAgentManager class

> +        """ Constructor for OmAgentManager class

>   

>           Args:

>               version (SaVersionT): IMM OM API version

> @@ -79,11 +79,11 @@ class ImmOmAgentManager(object):

>           self.selection_object = None

>   

>       def __enter__(self):

> -        """ Enter method for ImmOmAgentManager class """

> +        """ Enter method for OmAgentManager class """

>           return self

>   

>       def __exit__(self, exception_type, exception_value, traceback):

> -        """ Exit method for ImmOmAgentManager class

> +        """ Exit method for OmAgentManager class

>   

>           Finalize the IMM OM agent handle

>           """

> @@ -92,7 +92,7 @@ class ImmOmAgentManager(object):

>               self.handle = None

>   

>       def __del__(self):

> -        """ Destructor for ImmOmAgentManager class

> +        """ Destructor for OmAgentManager class

>   

>           Finalize the IMM OM agent handle

>           """

> @@ -149,7 +149,8 @@ class ImmOmAgentManager(object):

>               if rc != eSaAisErrorT.SA_AIS_OK:

>                   log_err("saImmOmFinalize FAILED - %s" %

>                           eSaAisErrorT.whatis(rc))

> -            elif rc == eSaAisErrorT.SA_AIS_OK \

> +

> +            if rc == eSaAisErrorT.SA_AIS_OK \

>                       or rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:

>                   # If the Finalize() call returned BAD_HANDLE, the handle 
> should

>                   # already become stale and invalid, so we reset it anyway.

> @@ -157,7 +158,7 @@ class ImmOmAgentManager(object):

>           return rc

>   

>   

> -class ImmOmAgent(ImmOmAgentManager):

> +class OmAgent(OmAgentManager):

>       """ This class acts as a high-level IMM OM agent, providing IMM OM

>       functions to the users at a higher level, and relieving the users of the

>       need to manage the life cycle of the IMM OM agent """

> @@ -265,8 +266,8 @@ class ImmOmAgent(ImmOmAgentManager):

>           Returns:

>               SaAisErrorT: Return code of the corresponding IMM API call(s)

>           """

> -        _owner = ImmOmAdminOwner(self.handle)

> -        rc = _owner.initialize()

> +        _owner = OmAdminOwner(self.handle)

> +        rc = _owner.init()

>           if rc == eSaAisErrorT.SA_AIS_OK:

>               index = dn.rfind(",")

>               object_rdn = dn[index+1:]

> @@ -314,10 +315,10 @@ class ImmOmAgent(ImmOmAgentManager):

>           return c_category.value

>   

>   

> -class ImmOmAdminOwner(object):

> +class OmAdminOwner(object):

>       """ This class encapsulates the ImmOm Admin Owner interface """

>       def __init__(self, imm_handle, owner_name=""):

> -        """ Constructor for ImmOmAdminOwner class

> +        """ Constructor for OmAdminOwner class

>   

>           Args:

>               imm_handle (SaImmHandleT): IMM OM agent handle

> @@ -333,11 +334,11 @@ class ImmOmAdminOwner(object):

>           self.owner_handle = None

>   

>       def __enter__(self):

> -        """ Enter method for ImmOmAdminOwner class """

> +        """ Enter method for OmAdminOwner class """

>           return self

>   

>       def __exit__(self, exception_type, exception_value, traceback):

> -        """ Exit method for ImmOmAdminOwner class

> +        """ Exit method for OmAdminOwner class

>   

>           Finalize the admin owner handle

>           """

> @@ -346,7 +347,7 @@ class ImmOmAdminOwner(object):

>               self.owner_handle = None

>   

>       def __del__(self):

> -        """ Destructor for ImmOmAdminOwner class

> +        """ Destructor for OmAdminOwner class

>   

>           Finalize the admin owner handle

>           """

> @@ -354,7 +355,7 @@ class ImmOmAdminOwner(object):

>               saImmOm.saImmOmAdminOwnerFinalize(self.owner_handle)

>               self.owner_handle = None

>   

> -    def initialize(self):

> +    def init(self):

>           """ Initialize the IMM admin owner interface

>   

>           Return:

> diff --git a/python/pyosaf/utils/immom/ccb.py 
> b/python/pyosaf/utils/immom/ccb.py

> index 042a726..15b891b 100644

> --- a/python/pyosaf/utils/immom/ccb.py

> +++ b/python/pyosaf/utils/immom/ccb.py

> @@ -21,12 +21,13 @@ from ctypes import c_void_p, pointer, cast, POINTER

>   

>   from pyosaf.saAis import eSaAisErrorT, SaNameT, SaStringT, SaFloatT, \

>       unmarshalNullArray, SaDoubleT, SaTimeT, SaUint64T, SaInt64T, SaUint32T, 
> \

> -    SaInt32T, SaVersionT

> +    SaInt32T

>   from pyosaf.saImm import eSaImmScopeT, eSaImmValueTypeT, SaImmAttrValuesT_2

>   from pyosaf import saImm

>   from pyosaf import saImmOm

>   from pyosaf.utils.immom import agent

> -from pyosaf.utils.immom.accessor import ImmOmAccessor

> +from pyosaf.utils.immom.agent import OmAgent

> +from pyosaf.utils.immom.accessor import Accessor

>   from pyosaf.utils import log_err, bad_handle_retry

>   

>   

> @@ -83,12 +84,11 @@ def marshal_c_array(value_type, value_list):

>       return c_array

>   

>   

> -class Ccb(object):

> +class Ccb(OmAgent):

>       """ Class representing an ongoing CCB """

>       def __init__(self, flags=saImm.saImm.SA_IMM_CCB_REGISTERED_OI,

>                    version=None):

> -        self.init_version = version if version else SaVersionT('A', 2, 15)

> -        self.imm_om = None

> +        super(Ccb, self).__init__(version=version)

>           self.admin_owner = None

>           self.accessor = None

>           self.ccb_handle = None

> @@ -123,43 +123,13 @@ class Ccb(object):

>           if self.ccb_handle is not None:

>               saImmOm.saImmOmCcbFinalize(self.ccb_handle)

>               self.ccb_handle = None

> +

>           if self.admin_owner:

>               del self.admin_owner

> -        if self.imm_om:

> -            del self.imm_om

> -

> -    def clear_admin_owner(self, obj_name, scope=eSaImmScopeT.SA_IMM_SUBTREE):

> -        """ Clear the admin owner for the set of object identified by the 
> scope

> -        and obj_name parameters

> -

> -        Args:

> -            obj_name (str): Object name

> -            scope (SaImmScopeT): Scope of the clear operation

> -

> -        Returns:

> -            SaAisErrorT: Return code of the corresponding IMM API call(s)

> -        """

> -        return self.imm_om.clear_admin_owner(obj_name, scope)

> -

> -    def finalize(self):

> -        """ Finalize the CCB handle

> -

> -        Returns:

> -            SaAisErrorT: Return code of the saImmOmCcbFinalize() API call

> -        """

> -        rc = eSaAisErrorT.SA_AIS_OK

> -        if self.ccb_handle:

> -            rc = agent.saImmOmCcbFinalize(self.ccb_handle)

> -            if rc != eSaAisErrorT.SA_AIS_OK:

> -                log_err("saImmOmCcbFinalize FAILED - %s" %

> -                        eSaAisErrorT.whatis(rc))

> -            elif rc == eSaAisErrorT.SA_AIS_OK \

> -                    or rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:

> -                # If the Finalize() call returned BAD_HANDLE, the handle 
> should

> -                # already become stale and invalid, so we reset it anyway.

> -                self.ccb_handle = None

>   

> -        return rc

> +        if self.handle is not None:

> +            saImmOm.saImmOmFinalize(self.handle)

> +            self.handle = None

>   

>       @bad_handle_retry

>       def init(self, owner_name=""):

> @@ -171,26 +141,22 @@ class Ccb(object):

>           Return:

>               SaAisErrorT: Return code of the corresponding IMM API calls

>           """

> -        # Clean previous resources if any

> -        self.finalize()

> -        self.imm_om = agent.ImmOmAgent(self.init_version)

> -        rc = self.imm_om.init()

> +        rc = super(Ccb, self).init()

>           if rc == eSaAisErrorT.SA_AIS_OK:

> -            _om_handle = self.imm_om.get_handle()

> -            self.admin_owner = agent.ImmOmAdminOwner(_om_handle, owner_name)

> -            self.admin_owner.initialize()

> +            self.admin_owner = agent.OmAdminOwner(self.handle, owner_name)

> +            rc = self.admin_owner.init()

> +

>               if rc == eSaAisErrorT.SA_AIS_OK:

>                   _owner_handle = self.admin_owner.get_handle()

>                   self.ccb_handle = saImmOm.SaImmCcbHandleT()

>   

> -                rc = agent.saImmOmCcbInitialize(

> -                    _owner_handle, self.ccb_flags, self.ccb_handle)

> +                rc = agent.saImmOmCcbInitialize(_owner_handle, 
> self.ccb_flags,

> +                                                self.ccb_handle)

>                   if rc != eSaAisErrorT.SA_AIS_OK:

>                       log_err("saImmOmCcbInitialize FAILED - %s" %

>                               eSaAisErrorT.whatis(rc))

>           return rc

>   

> -    @bad_handle_retry

>       def create(self, obj, parent_name=None):

>           """ Create the CCB object

>   

> @@ -237,7 +203,6 @@ class Ccb(object):

>   

>           return rc

>   

> -    @bad_handle_retry

>       def delete(self, object_name):

>           """ Add a delete operation of the object with the given DN to the 
> CCB

>   

> @@ -269,7 +234,6 @@ class Ccb(object):

>   

>           return rc

>   

> -    @bad_handle_retry

>       def _modify(self, object_name, attr_name, values, mod_type):

>           """ Modify an existing object

>   

> @@ -285,7 +249,7 @@ class Ccb(object):

>               rc = eSaAisErrorT.SA_AIS_ERR_INVALID_PARAM

>           else:

>               if not self.accessor:

> -                self.accessor = ImmOmAccessor(self.init_version)

> +                self.accessor = Accessor(self.init_version)

>                   self.accessor.init()

>   

>               # Get the attribute value type by reading the object's class

> @@ -293,8 +257,7 @@ class Ccb(object):

>               rc, obj = self.accessor.get(object_name)

>               if rc == eSaAisErrorT.SA_AIS_OK:

>                   class_name = obj.SaImmAttrClassName

> -                _, attr_def_list = \

> -                    self.imm_om.get_class_description(class_name)

> +                _, attr_def_list = self.get_class_description(class_name)

>                   value_type = None

>                   for attr_def in attr_def_list:

>                       if attr_def.attrName == attr_name:

> diff --git a/python/pyosaf/utils/immom/iterator.py 
> b/python/pyosaf/utils/immom/iterator.py

> index 51f7e95..7402c94 100644

> --- a/python/pyosaf/utils/immom/iterator.py

> +++ b/python/pyosaf/utils/immom/iterator.py

> @@ -30,7 +30,7 @@ from pyosaf.utils.immom import agent

>   from pyosaf.utils.immom.object import ImmObject

>   

>   

> -class SearchIterator(agent.ImmOmAgentManager, Iterator):

> +class SearchIterator(agent.OmAgentManager, Iterator):

>       """ General search iterator """

>       def __init__(self, root_name=None, scope=eSaImmScopeT.SA_IMM_SUBTREE,

>                    attribute_names=None, search_param=None, version=None):

> @@ -109,7 +109,7 @@ class SearchIterator(agent.ImmOmAgentManager, Iterator):

>                                       
> [unmarshalSaImmValue(attr.attrValues[val],

>                                                            attr.attrValueType)

>                                        for val in attr_range]]

> -        return ImmObject(obj_name, attrs)

> +        return ImmObject(str(obj_name), attrs)

>   

>       @bad_handle_retry

>       def init(self):

> diff --git a/python/pyosaf/utils/immom/object.py 
> b/python/pyosaf/utils/immom/object.py

> index 0cef920..435a244 100644

> --- a/python/pyosaf/utils/immom/object.py

> +++ b/python/pyosaf/utils/immom/object.py

> @@ -20,7 +20,7 @@ from pyosaf.saAis import eSaAisErrorT

>   from pyosaf.saImm import saImm

>   

>   from pyosaf.utils import SafException

> -from pyosaf.utils.immom.agent import ImmOmAgent

> +from pyosaf.utils.immom.agent import OmAgent

>   

>   

>   class ImmObject(object):

> @@ -43,7 +43,7 @@ class ImmObject(object):

>                   is not SA_AIS_OK

>           """

>           self.__dict__["dn"] = dn

> -        _imm_om = ImmOmAgent()

> +        _imm_om = OmAgent()

>           rc = _imm_om.init()

>           if rc != eSaAisErrorT.SA_AIS_OK:

>               raise SafException(rc)

 

 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to