Hi Hans, Anders & Srinivas,

Just reminding.
Please spend a little time to help me review this patch.

Many thanks,
Hieu


-----Original Message-----
From: Hieu Nguyen [mailto:hieu.t.ngu...@dektech.com.au] 
Sent: Wednesday, December 6, 2017 2:46 PM
To: hans.nordeb...@ericsson.com; anders.wid...@ericsson.com;
srinivas.mangip...@oracle.com
Cc: opensaf-devel@lists.sourceforge.net; Hieu Nguyen
<hieu.t.ngu...@dektech.com.au>
Subject: [PATCH 1/1] pyosaf: refactor IMM utils [#2683]

+ 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 | 141 ++++----
 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, 736 insertions(+), 557 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
+# 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..1c9f0d8 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
@@ -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)
-- 
2.7.4



------------------------------------------------------------------------------
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
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to