agent.py:
  - Update some default values for notificationSend.
  - Correct NtfAgent.finalize() to handle BAD_HANDLE error code.
producer.py:
  - Fix type conversion when assigning value of type SaNtfValueT.
  - Keep the notification info for reuse after sending notification.
  - Update the assigning of specificProblems for alarm notification.
  - Harden 'None' value checking.
subscriber.py:
  - Support handling of long-dn objects in subscribed/read notifications.
  - Fix the parsing of additionalText and specificProblems in
    subscribed/read notifications.
  - Explicitly free the notification after parsing to avoid memory leak.
  - Fix some semantic errors.
reader.py:
  - Add the missing function to set search direction when creating
    filter for notificationRead.
  - Check filterAllocate result before initializing notificationRead.
---
 python/pyosaf/utils/ntf/__init__.py   | 18 +++++++++++
 python/pyosaf/utils/ntf/agent.py      |  9 +++---
 python/pyosaf/utils/ntf/producer.py   | 59 ++++++++++++++---------------------
 python/pyosaf/utils/ntf/reader.py     | 29 +++++++++++------
 python/pyosaf/utils/ntf/subscriber.py | 45 +++++++++++++++++---------
 5 files changed, 98 insertions(+), 62 deletions(-)

diff --git a/python/pyosaf/utils/ntf/__init__.py 
b/python/pyosaf/utils/ntf/__init__.py
index 0687517..3935a98 100644
--- a/python/pyosaf/utils/ntf/__init__.py
+++ b/python/pyosaf/utils/ntf/__init__.py
@@ -106,6 +106,9 @@ def send_object_create_notification(vendor_id, major_id, 
minor_id,
     if rc != eSaAisErrorT.SA_AIS_OK:
         raise SafException(rc)
 
+    # Clear the internally saved notification information
+    _ntf_producer.clear_info()
+
     return rc
 
 
@@ -158,6 +161,9 @@ def send_object_delete_notification(vendor_id, major_id, 
minor_id,
     if rc != eSaAisErrorT.SA_AIS_OK:
         raise SafException(rc)
 
+    # Clear the internally saved notification information
+    _ntf_producer.clear_info()
+
     return rc
 
 
@@ -211,6 +217,9 @@ def send_attribute_change_notification(
     if rc != eSaAisErrorT.SA_AIS_OK:
         raise SafException(rc)
 
+    # Clear the internally saved notification information
+    _ntf_producer.clear_info()
+
     return rc
 
 
@@ -266,6 +275,9 @@ def send_state_change_notification(vendor_id,
     if rc != eSaAisErrorT.SA_AIS_OK:
         raise SafException(rc)
 
+    # Clear the internally saved notification information
+    _ntf_producer.clear_info()
+
     return rc
 
 
@@ -316,6 +328,9 @@ def send_alarm_notification(
     if rc != eSaAisErrorT.SA_AIS_OK:
         raise SafException(rc)
 
+    # Clear the internally saved notification information
+    _ntf_producer.clear_info()
+
     return rc
 
 
@@ -378,6 +393,9 @@ def send_security_alarm_notification(
     if rc != eSaAisErrorT.SA_AIS_OK:
         raise SafException(rc)
 
+    # Clear the internally saved notification information
+    _ntf_producer.clear_info()
+
     return rc
 
 
diff --git a/python/pyosaf/utils/ntf/agent.py b/python/pyosaf/utils/ntf/agent.py
index dd2d218..34e2969 100644
--- a/python/pyosaf/utils/ntf/agent.py
+++ b/python/pyosaf/utils/ntf/agent.py
@@ -112,13 +112,14 @@ class NotificationInfo(object):
         self.probable_cause = \
             saNtf.eSaNtfProbableCauseT.SA_NTF_UNSPECIFIED_REASON
         self.specific_problems = []
-        self.perceived_severity = saNtf.eSaNtfSeverityT.SA_NTF_SEVERITY_MINOR
-        self.trend = None
+        self.perceived_severity = \
+            saNtf.eSaNtfSeverityT.SA_NTF_SEVERITY_INDETERMINATE
+        self.trend = saNtf.eSaNtfSeverityTrendT.SA_NTF_TREND_NO_CHANGE
         self.threshold_information = None
         self.monitored_attrs = []
         self.proposed_repair_actions = []
         # Security alarm info
-        self.severity = saNtf.eSaNtfSeverityT.SA_NTF_SEVERITY_MINOR
+        self.severity = saNtf.eSaNtfSeverityT.SA_NTF_SEVERITY_INDETERMINATE
         self.security_alarm_detector = None
         self.service_user = None
         self.service_provider = None
@@ -491,7 +492,7 @@ class NtfAgent(object):
             rc = saNtfFinalize(self.handle)
             if rc != eSaAisErrorT.SA_AIS_OK:
                 log_err("saNtfFinalize 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
diff --git a/python/pyosaf/utils/ntf/producer.py 
b/python/pyosaf/utils/ntf/producer.py
index cea5585..1d54225 100644
--- a/python/pyosaf/utils/ntf/producer.py
+++ b/python/pyosaf/utils/ntf/producer.py
@@ -58,7 +58,7 @@ class NtfProducer(ntf.NtfAgent):
             attr_value.uint8Val = int(value)
 
         elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_INT8:
-            attr_value.int8Val = int(value)
+            attr_value.int8Val = value
 
         elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_UINT16:
             attr_value.uint16Val = int(value)
@@ -73,7 +73,7 @@ class NtfProducer(ntf.NtfAgent):
             attr_value.int32Val = int(value)
 
         elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_FLOAT:
-            attr_value.floatVal = int(value)
+            attr_value.floatVal = float(value)
 
         elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_UINT64:
             attr_value.uint64Val = int(value)
@@ -82,11 +82,11 @@ class NtfProducer(ntf.NtfAgent):
             attr_value.int64Val = int(value)
 
         elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_DOUBLE:
-            attr_value.doubleVal = int(value)
+            attr_value.doubleVal = float(value)
 
-        elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_LDAP_NAME or \
-            value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_STRING or \
-                value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_IPADDRESS:
+        elif value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_LDAP_NAME \
+                or value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_STRING \
+                or value_type == saNtf.eSaNtfValueTypeT.SA_NTF_VALUE_IPADDRESS:
             len_value = len(value)
             dest_ptr = SaVoidPtr()
             rc = ntf.saNtfPtrValAllocate(ntf_handle, len_value + 1, dest_ptr,
@@ -230,8 +230,8 @@ class NtfProducer(ntf.NtfAgent):
         """ Fill in the thresholdInformation field in alarm notification
 
         Args:
-            threshold_information (list(ThresholdInformation)): List of
-                ThresholdInformation structures
+            threshold_information (ThresholdInformation):
+                A ThresholdInformation structure
         """
         self.ntf_info.threshold_information = threshold_information
 
@@ -375,8 +375,6 @@ class NtfProducer(ntf.NtfAgent):
             if rc != eSaAisErrorT.SA_AIS_OK:
                 log_err("saNtfNotificationSend FAILED, rc = %s" %
                         eSaAisErrorT.whatis(rc))
-            else:
-                self.clear_info()
 
             # Free the notification
             ntf.saNtfNotificationFree(notification.notificationHandle)
@@ -446,9 +444,6 @@ class NtfProducer(ntf.NtfAgent):
                 log_err("saNtfNotificationSend FAILED, rc = %s" %
                         eSaAisErrorT.whatis(rc))
 
-            else:
-                self.clear_info()
-
             # Free the notification
             ntf.saNtfNotificationFree(notification.notificationHandle)
 
@@ -508,8 +503,6 @@ class NtfProducer(ntf.NtfAgent):
             if rc != eSaAisErrorT.SA_AIS_OK:
                 log_err("saNtfNotificationSend FAILED, rc = %s" %
                         eSaAisErrorT.whatis(rc))
-            else:
-                self.clear_info()
 
             # Free the notification
             ntf.saNtfNotificationFree(notification.notificationHandle)
@@ -554,24 +547,26 @@ class NtfProducer(ntf.NtfAgent):
             notification.probableCause.contents.value = \
                 self.ntf_info.probable_cause
 
+            notification.perceivedSeverity.contents.value = \
+                self.ntf_info.perceived_severity
+
+            if self.ntf_info.trend is not None:
+                notification.trend.contents.value = self.ntf_info.trend
+
             for i, problem in enumerate(self.ntf_info.specific_problems):
                 ptr = notification.specificProblems[i]
                 ptr.problemId = problem.problem_id
-                ptr.problemClassId.vendorId = problem.problem_class_id.vendorId
-                ptr.problemClassId.majorId = problem.problem_class_id.majorId
-                ptr.problemClassId.minorId = problem.problem_class_id.minorId
+                if problem.problem_class_id is not None:
+                    prob_class_id = problem.problem_class_id
+                    ptr.problemClassId.vendorId = prob_class_id.vendorId
+                    ptr.problemClassId.majorId = prob_class_id.majorId
+                    ptr.problemClassId.minorId = prob_class_id.minorId
                 ptr.problemType = problem.problem_type
                 self._assign_ntf_value(
                     notification.notificationHandle, ptr.problemValue,
                     problem.problem_value, problem.problem_type)
 
-            notification.perceivedSeverity.contents.value = \
-                self.ntf_info.perceived_severity
-
-            if self.ntf_info.trend:
-                notification.trend.contents.value = self.ntf_info.trend
-
-            if self.ntf_info.threshold_information:
+            if self.ntf_info.threshold_information is not None:
                 ptr = notification.thresholdInformation.contents
                 ptr.thresholdId = \
                     self.ntf_info.threshold_information.threshold_id
@@ -592,9 +587,6 @@ class NtfProducer(ntf.NtfAgent):
                     ptr.thresholdValueType)
                 ptr.armTime = self.ntf_info.threshold_information.arm_time
 
-            notification.perceivedSeverity.contents.value = \
-                self.ntf_info.perceived_severity
-
             for i, attribute in enumerate(self.ntf_info.monitored_attrs):
                 ptr = notification.monitoredAttributes[i]
 
@@ -620,8 +612,6 @@ class NtfProducer(ntf.NtfAgent):
             if rc != eSaAisErrorT.SA_AIS_OK:
                 log_err("saNtfNotificationSend FAILED, rc = %s" %
                         eSaAisErrorT.whatis(rc))
-            else:
-                self.clear_info()
 
             # Free the notification
             ntf.saNtfNotificationFree(notification.notificationHandle)
@@ -663,7 +653,7 @@ class NtfProducer(ntf.NtfAgent):
                 self.ntf_info.probable_cause
             notification.severity.contents.value = self.ntf_info.severity
 
-            if self.ntf_info.security_alarm_detector:
+            if self.ntf_info.security_alarm_detector is not None:
                 notification.securityAlarmDetector.contents.valueType = \
                     self.ntf_info.security_alarm_detector.value_type
                 self._assign_ntf_value(
@@ -672,14 +662,15 @@ class NtfProducer(ntf.NtfAgent):
                     self.ntf_info.security_alarm_detector.value,
                     self.ntf_info.security_alarm_detector.value_type)
 
-            if self.ntf_info.service_user:
+            if self.ntf_info.service_user is not None:
                 notification.serviceUser.contents.valueType = \
                     self.ntf_info.service_user.value_type
                 self._assign_ntf_value(notification.notificationHandle,
                                        notification.serviceUser.contents.value,
                                        self.ntf_info.service_user.value,
                                        self.ntf_info.service_user.value_type)
-            if self.ntf_info.service_provider:
+
+            if self.ntf_info.service_provider is not None:
                 notification.serviceProvider.contents.valueType = \
                     self.ntf_info.service_provider.value_type
                 self._assign_ntf_value(
@@ -693,8 +684,6 @@ class NtfProducer(ntf.NtfAgent):
             if rc != eSaAisErrorT.SA_AIS_OK:
                 log_err("saNtfNotificationSend FAILED, rc = %s" %
                         eSaAisErrorT.whatis(rc))
-            else:
-                self.clear_info()
 
             # Free the notification
             ntf.saNtfNotificationFree(notification.notificationHandle)
diff --git a/python/pyosaf/utils/ntf/reader.py 
b/python/pyosaf/utils/ntf/reader.py
index 560ecd8..b633482 100644
--- a/python/pyosaf/utils/ntf/reader.py
+++ b/python/pyosaf/utils/ntf/reader.py
@@ -131,6 +131,14 @@ class NtfReader(NtfConsumer, Iterator):
         """
         self.search_criteria = search_criteria
 
+    def set_search_direction(self, search_direction):
+        """ Set the notification search direction
+
+        Args:
+            search_direction (SaNtfSearchDirectionT): Search direction
+        """
+        self.search_direction = search_direction
+
     @bad_handle_retry
     def read(self, notification_types=None):
         """ Start reading NTF notifications with the types specified in the
@@ -162,19 +170,22 @@ class NtfReader(NtfConsumer, Iterator):
                     and security_alarm_type not in notification_types:
                 return eSaAisErrorT.SA_AIS_ERR_NOT_SUPPORTED
 
+        rc = eSaAisErrorT.SA_AIS_OK
         # Generate the alarm notification filter
         if notification_types is None or alarm_type in notification_types:
-            self._generate_alarm_filter()
+            rc = self._generate_alarm_filter()
 
         # Generate the security alarm notification filter
-        if notification_types is None \
-                or security_alarm_type in notification_types:
-            self._generate_security_alarm_filter()
-
-        self.read_handle = saNtf.SaNtfReadHandleT()
-        rc = ntf.saNtfNotificationReadInitialize(self.search_criteria,
-                                                 self.filter_handles,
-                                                 self.read_handle)
+        if rc == eSaAisErrorT.SA_AIS_OK:
+            if notification_types is None \
+                    or security_alarm_type in notification_types:
+                rc = self._generate_security_alarm_filter()
+
+        if rc == eSaAisErrorT.SA_AIS_OK:
+            self.read_handle = saNtf.SaNtfReadHandleT()
+            rc = ntf.saNtfNotificationReadInitialize(self.search_criteria,
+                                                     self.filter_handles,
+                                                     self.read_handle)
         if rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:
             init_rc = self.init()
             # If the re-initialization of agent handle succeeds, we still need
diff --git a/python/pyosaf/utils/ntf/subscriber.py 
b/python/pyosaf/utils/ntf/subscriber.py
index 5eea9da..f9c9fad 100644
--- a/python/pyosaf/utils/ntf/subscriber.py
+++ b/python/pyosaf/utils/ntf/subscriber.py
@@ -160,7 +160,7 @@ class NtfConsumer(ntf.NtfAgent):
             perceived_severities (list(SaNtfSeverityT)): List of alarm
                 severities
         """
-        self.filter_info.probable_cause_list = perceived_severities
+        self.filter_info.perceived_severity_list = perceived_severities
 
     def set_filter_trends(self, trends):
         """ Set data for the trends field in the notification filter header of
@@ -396,7 +396,7 @@ class NtfConsumer(ntf.NtfAgent):
             len(self.filter_info.probable_cause_list),
             len(self.filter_info.severity_list), 0, 0, 0)
         if rc != eSaAisErrorT.SA_AIS_OK:
-            log_err("saNtfAlarmNotificationFilterAllocate FAILED, "
+            log_err("saNtfSecurityAlarmNotificationFilterAllocate FAILED, "
                     "rc = %s" % eSaAisErrorT.whatis(rc))
         else:
             self.filter_handles.securityAlarmFilterHandle = \
@@ -495,17 +495,19 @@ class NtfConsumer(ntf.NtfAgent):
         """
         ntf_info = ntf.NotificationInfo()
         ntf_info.event_type = ntf_header.eventType.contents.value
-        ntf_info.notification_object = \
-            ntf_header.notificationObject.contents.value
-        ntf_info.notifying_object = \
-            ntf_header.notifyingObject.contents.value
+        ntf_info.notification_object = ntf_header.notificationObject.contents
+        ntf_info.notifying_object = ntf_header.notifyingObject.contents
         ntf_info.ntf_class_id = \
             ntf_header.notificationClassId.contents
         ntf_info.event_time = ntf_header.eventTime.contents.value
         ntf_info.notification_id = \
             ntf_header.notificationId.contents.value
-        ntf_info.additional_text = \
-            ntf_header.additionalText[0:ntf_header.lengthAdditionalText]
+
+        additional_text_str = \
+            ctypes.create_string_buffer(ntf_header.lengthAdditionalText)
+        ctypes.memmove(additional_text_str, ntf_header.additionalText,
+                       ntf_header.lengthAdditionalText)
+        ntf_info.additional_text = additional_text_str.value
 
         for i in range(ntf_header.numAdditionalInfo):
             c_add_info = ntf_header.additionalInfo[i]
@@ -603,10 +605,6 @@ class NtfConsumer(ntf.NtfAgent):
         """
         ntf_handle = c_ntf.notificationHandle
         ntf_info.probable_cause = c_ntf.probableCause.contents.value
-
-        for i in range(c_ntf.numSpecificProblems):
-            ntf_info.specific_problems.append(
-                c_ntf.specificProblems[i])
         ntf_info.perceived_severity = c_ntf.perceivedSeverity.contents.value
         ntf_info.trend = c_ntf.trend.contents.value
 
@@ -634,6 +632,18 @@ class NtfConsumer(ntf.NtfAgent):
 
             ntf_info.threshold_information = threshold_info
 
+        for i in range(c_ntf.numSpecificProblems):
+            c_specific_problem = c_ntf.specificProblems[i]
+            spec_problem = ntf.SpecificProblem()
+            spec_problem.problem_id = c_specific_problem.problemId
+            spec_problem.problem_class_id = c_specific_problem.problemClassId
+            spec_problem.problem_type = c_specific_problem.problemType
+            spec_problem.problem_value = \
+                self._get_ntf_value(ntf_handle,
+                                    c_specific_problem.problemValue,
+                                    c_specific_problem.problemType)
+            ntf_info.specific_problems.append(spec_problem)
+
         for i in range(c_ntf.numMonitoredAttributes):
             c_attr = c_ntf.monitoredAttributes[i]
             attr = ntf.Attribute()
@@ -758,8 +768,15 @@ class NtfSubscriber(NtfConsumer):
         else:
             return
 
+        # Make a deep copy of the parsed notification for use after freeing it
+        ntf_info_copy = deepcopy(ntf_info)
+
         # Send the ntf info to user's callback function
-        self.ntf_notif_function(subscription_id, notification_type, ntf_info)
+        self.ntf_notif_function(subscription_id, notification_type,
+                                ntf_info_copy)
+
+        # Free the notification after parsing for needed information
+        ntf.saNtfNotificationFree(notification.notificationHandle)
 
     def _ntf_notif_discarded_callback(self, c_subscription_id,
                                       c_notification_type, c_number_discarded,
@@ -823,7 +840,7 @@ class NtfSubscriber(NtfConsumer):
         if rc == eSaAisErrorT.SA_AIS_OK:
             rc = self._fetch_sel_obj()
             if rc == eSaAisErrorT.SA_AIS_ERR_BAD_HANDLE:
-                self._re_init()
+                rc = self._re_init()
         return rc
 
     @bad_handle_retry
-- 
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to