ack, code review only./Thanks HansN

On 12/20/2017 09:22 AM, Nguyen Luu wrote:
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


------------------------------------------------------------------------------
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