---
python/pyosaf/utils/__init__.py | 44 +++++++++++++++++++++++++++++++++++
python/pyosaf/utils/clm/__init__.py | 11 +++++----
python/pyosaf/utils/immoi/__init__.py | 7 +++---
python/pyosaf/utils/immom/__init__.py | 7 +++---
python/pyosaf/utils/log/__init__.py | 4 ++--
python/pyosaf/utils/ntf/__init__.py | 16 ++++++-------
6 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/python/pyosaf/utils/__init__.py b/python/pyosaf/utils/__init__.py
index 0d4b648..3776cef 100644
--- a/python/pyosaf/utils/__init__.py
+++ b/python/pyosaf/utils/__init__.py
@@ -16,6 +16,7 @@
############################################################################
import time
+from copy import deepcopy
from pyosaf.saAis import eSaAisErrorT
@@ -70,3 +71,46 @@ def decorate(function):
return error
return inner
+
+
+def initialize_decorate(function):
+ ''' Decorate the given SAF initialize(handle, callbacks, version) so that
+ it retries a fixed number of times if needed with the same arguments
and
+ raises an exception if it encounters any fault other than
+ SA_AIS_ERR_TRY_AGAIN.
+ '''
+
+ def inner(*args):
+ ''' Calls "function" in the lexical scope in a retry loop and raises
+ an exception if it encounters any other faults.
+
+ Args:
+ args(tuple): Argument of initialize() with format:
+ tuple(handle, callbacks, version)
+ '''
+ # Backup current version
+ backup_version = deepcopy(args[2])
+
+ one_sec_sleeps = 0
+ error = function(*args)
+
+ while error == eSaAisErrorT.SA_AIS_ERR_TRY_AGAIN:
+ if one_sec_sleeps == TRY_AGAIN_COUNT:
+ break
+
+ time.sleep(1)
+ one_sec_sleeps += 1
+
+ # If SAF initialize() returns ERR_TRY_AGAIN, the version will be
+ # updated to the latest version, so set original version on
+ # next initialization.
+ version = deepcopy(backup_version)
+ args = args[:2] + (version,)
+ error = function(*args)
+
+ if error != eSaAisErrorT.SA_AIS_OK:
+ raise_saf_exception(function, error)
+
+ return error
+
+ return inner
diff --git a/python/pyosaf/utils/clm/__init__.py
b/python/pyosaf/utils/clm/__init__.py
index 9b9e11f..b9b853a 100644
--- a/python/pyosaf/utils/clm/__init__.py
+++ b/python/pyosaf/utils/clm/__init__.py
@@ -20,12 +20,13 @@
from pyosaf import saClm, saAis
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
+
# Decorate the raw saClm* functions with retry and raising exceptions
-saClmInitialize = decorate(saClm.saClmInitialize)
-saClmInitialize_3 = decorate(saClm.saClmInitialize_3)
-saClmInitialize_4 = decorate(saClm.saClmInitialize_4)
+saClmInitialize = initialize_decorate(saClm.saClmInitialize)
+saClmInitialize_3 = initialize_decorate(saClm.saClmInitialize_3)
+saClmInitialize_4 = initialize_decorate(saClm.saClmInitialize_4)
saClmSelectionObjectGet = decorate(saClm.saClmSelectionObjectGet)
saClmDispatch = decorate(saClm.saClmDispatch)
saClmFinalize = decorate(saClm.saClmFinalize)
@@ -131,7 +132,7 @@ def track(flags=saAis.saAis.SA_TRACK_CHANGES_ONLY):
def get_members():
notification_buffer = saClm.SaClmClusterNotificationBufferT_4()
- saClmClusterTrack_4(HANDLE, saAis.saAis.SA_TRACK_CURRENT,
+ saClmClusterTrack_4(HANDLE, saAis.saAis.SA_TRACK_CURRENT,
notification_buffer)
cluster_nodes = []
diff --git a/python/pyosaf/utils/immoi/__init__.py
b/python/pyosaf/utils/immoi/__init__.py
index 02ad89b..2ea0f33 100644
--- a/python/pyosaf/utils/immoi/__init__.py
+++ b/python/pyosaf/utils/immoi/__init__.py
@@ -38,7 +38,7 @@ 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 import decorate
+from pyosaf.utils import decorate, initialize_decorate
from ctypes import c_char_p, c_void_p, cast, pointer
@@ -49,8 +49,9 @@ TRYAGAIN_CNT = 60
OPENSAF_IMM_OBJECT = "opensafImm=opensafImm,safApp=safImmService"
+
# Decorate the raw saImmOi* functions with retry and raising exceptions
-saImmOiInitialize_2 = decorate(saImmOi.saImmOiInitialize_2)
+saImmOiInitialize_2 = initialize_decorate(saImmOi.saImmOiInitialize_2)
saImmOiSelectionObjectGet = decorate(saImmOi.saImmOiSelectionObjectGet)
saImmOiDispatch = decorate(saImmOi.saImmOiDispatch)
saImmOiFinalize = decorate(saImmOi.saImmOiFinalize)
@@ -71,9 +72,7 @@ saImmOiCcbSetErrorString =
decorate(saImmOi.saImmOiCcbSetErrorString)
def initialize(callbacks=None):
''' Initializes IMM OI '''
-
version = SaVersionT('A', 2, 15)
-
saImmOiInitialize_2(HANDLE, callbacks, version)
diff --git a/python/pyosaf/utils/immom/__init__.py b/python/pyosaf/utils/immom/__init__.py
index 09370c8..2246720 100644
--- a/python/pyosaf/utils/immom/__init__.py
+++ b/python/pyosaf/utils/immom/__init__.py
@@ -31,7 +31,7 @@ from pyosaf.saImm import eSaImmScopeT, unmarshalSaImmValue,
SaImmAttrNameT, \
from pyosaf.saImmOm import SaImmHandleT, SaImmAccessorHandleT,\
saImmOmAdminOwnerInitialize
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
from pyosaf.utils import SafException
from pyosaf.utils.immom.object import ImmObject
@@ -39,8 +39,9 @@ from pyosaf.utils.immom.object import ImmObject
HANDLE = saImmOm.SaImmHandleT()
ACCESSOR_HANDLE = SaImmAccessorHandleT()
+
# Decorate IMM functions to add retry loops and error handling
-saImmOmInitialize = decorate(saImmOm.saImmOmInitialize)
+saImmOmInitialize = initialize_decorate(saImmOm.saImmOmInitialize)
saImmOmSelectionObjectGet = decorate(saImmOm.saImmOmSelectionObjectGet)
saImmOmDispatch = decorate(saImmOm.saImmOmDispatch)
saImmOmFinalize = decorate(saImmOm.saImmOmFinalize)
@@ -75,9 +76,7 @@ saImmOmAdminOperationContinuationClear =
decorate(saImmOm.saImmOmAdminOperationC
def initialize():
''' saImmOmInitialize with TRYAGAIN handling '''
version = SaVersionT('A', 2, 15)
-
err = saImmOmInitialize(HANDLE, None, version)
-
err = saImmOmAccessorInitialize(HANDLE, ACCESSOR_HANDLE)
diff --git a/python/pyosaf/utils/log/__init__.py b/python/pyosaf/utils/log/__init__.py
index 152df61..4ac2bf8 100644
--- a/python/pyosaf/utils/log/__init__.py
+++ b/python/pyosaf/utils/log/__init__.py
@@ -20,12 +20,12 @@
'''
from pyosaf import saLog, saAis
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
LOG_VERSION = saAis.SaVersionT('A', 2, 1)
# Decorate LOG functions to add retry loops and error handling
-saLogInitialize = decorate(saLog.saLogInitialize)
+saLogInitialize = initialize_decorate(saLog.saLogInitialize)
saLogSelectionObjectGet = decorate(saLog.saLogSelectionObjectGet)
saLogDispatch = decorate(saLog.saLogDispatch)
saLogFinalize = decorate(saLog.saLogFinalize)
diff --git a/python/pyosaf/utils/ntf/__init__.py
b/python/pyosaf/utils/ntf/__init__.py
index 95df5f6..3355cc2 100644
--- a/python/pyosaf/utils/ntf/__init__.py
+++ b/python/pyosaf/utils/ntf/__init__.py
@@ -22,17 +22,18 @@
from pyosaf import saNtf, saAis
import ctypes
-from pyosaf.utils import decorate
+from pyosaf.utils import decorate, initialize_decorate
-saNtfInitialize = decorate(saNtf.saNtfInitialize)
+
+saNtfInitialize = initialize_decorate(saNtf.saNtfInitialize)
saNtfLocalizedMessageFree = decorate(saNtf.saNtfLocalizedMessageFree)
saNtfStateChangeNotificationFilterAllocate =
decorate(saNtf.saNtfStateChangeNotificationFilterAllocate)
saNtfNotificationUnsubscribe = decorate(saNtf.saNtfNotificationUnsubscribe)
saNtfNotificationReadInitialize =
decorate(saNtf.saNtfNotificationReadInitialize)
-saNtfInitialize_2 = decorate(saNtf.saNtfInitialize_2)
+saNtfInitialize_2 = initialize_decorate(saNtf.saNtfInitialize_2)
saNtfNotificationReadInitialize_2 =
decorate(saNtf.saNtfNotificationReadInitialize_2)
saNtfNotificationSubscribe = decorate(saNtf.saNtfNotificationSubscribe)
-saNtfInitialize_3 = decorate(saNtf.saNtfInitialize_3)
+saNtfInitialize_3 = initialize_decorate(saNtf.saNtfInitialize_3)
saNtfSelectionObjectGet = decorate(saNtf.saNtfSelectionObjectGet)
saNtfDispatch = decorate(saNtf.saNtfDispatch)
saNtfFinalize = decorate(saNtf.saNtfFinalize)
@@ -135,10 +136,6 @@ def dummy_func(*args):
def initialize(notification_callback=None):
''' Initializes the NTF library'''
-
- # Initialize the NTF API
- version = saAis.SaVersionT('A', 1, 1)
-
# Assign default values for callbacks
CALLBACKS.saNtfNotificationCallback = \
saNtf.SaNtfNotificationCallbackT(dummy_func)
@@ -150,6 +147,9 @@ def initialize(notification_callback=None):
CALLBACKS.saNtfNotificationCallback = \
saNtf.SaNtfNotificationCallbackT(notification_callback)
+ # Initialize the NTF API
+ version = saAis.SaVersionT('A', 1, 1)
+
# Initialize the API
saNtfInitialize(HANDLE, CALLBACKS, version)