Good comments for both this and Patch 9/9. In my system the object already 
existed so I missed the error you saw below. I have fixed and will send an 
updated version.

Thanks,
Johan

From: Hung Nguyen [mailto:[email protected]]
Sent: den 14 september 2015 10:59
To: Johan Mårtensson O; Hans Nordebäck; [email protected]; 
[email protected]
Cc: [email protected]
Subject: Re: [PATCH 2 of 9] pyosaf: Fix handling of attribute updates and 
associated sample applications [#1406]

Hi Johan,

Please see inline comments below.

BR,

Hùng Nguyễn - DEK Technologies


________________________________

From: Johan Mårtensson O
Sent: Thursday, September 03, 2015 10:25PM
To: Hans Nordeback, Mathivanan Naickan, Hung Nguyen, Srikanth Revanuru 
([email protected]<mailto:[email protected]>)
Cc: Opensaf-devel
Subject: [PATCH 2 of 9] pyosaf: Fix handling of attribute updates and 
associated sample applications [#1406]

 python/pyosaf/utils/immoi/__init__.py               |   3 -

 python/pyosaf/utils/immoi/implementer.py            |  64 +++++++++-----------

 python/pyosaf/utils/immom/__init__.py               |  10 ++-

 python/samples/immoi/samples/classes.xml            |  15 ++++

 python/samples/immoi/samples/users                  |  30 +++++++++

 python/samples/immoi/samples/users-inheritance-impl |  34 +++++++++++

 6 files changed, 118 insertions(+), 38 deletions(-)





Fix the handling of updates of runtime attributes on request from IMM. Add 
sample application to demonstrate this, both for direct callbacks and by using 
a subclass.



Verify by executing the sample applications:



./users &



immlist usersId=1



or



./users-inheritance-impl &



immlist usersId=2



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

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

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

@@ -281,9 +281,6 @@ def get_object_no_runtime(dn, class_name

     if not class_name:

         class_name = get_class_name_for_dn(dn)



-    if not class_name:

-        return None

-

[Hung] When I tried 'time-reporter' application, I got this error:



Traceback (most recent call last):

  File "./time-reporter", line 55, in <module>

    if not immoi.get_object_no_runtime(dn):

  File "/usr/local/lib/python2.7/dist-packages/pyosaf/utils/immoi/__init__.py", 
line 284, in get_object_no_runtime

    class_desc = get_class_description(class_name)

  File "/usr/local/lib/python2.7/dist-packages/pyosaf/utils/immoi/__init__.py", 
line 318, in get_class_description

    class_descriptions[class_name] = immom.class_description_get(class_name)

  File "/usr/local/lib/python2.7/dist-packages/pyosaf/utils/immom/__init__.py", 
line 134, in class_description_get

    attr_defs)

  File "/usr/local/lib/python2.7/dist-packages/pyosaf/utils/__init__.py", line 
68, in inner

    raise_saf_exception(function, error)

  File "/usr/local/lib/python2.7/dist-packages/pyosaf/utils/__init__.py", line 
42, in raise_saf_exception

    raise SafException(error, error_string)

pyosaf.utils.SafException: SA_AIS_ERR_INVALID_PARAM



saImmOmClassDescriptionGet_2() returned SA_AIS_ERR_INVALID_PARAM because of the 
NULL className parameter.

I think those lines should not be removed.

If 'dn' doesn't exist, get_class_name_for_dn() will return None and 
get_object_no_runtime() should return None.







     class_desc = get_class_description(class_name)



     config_attrs = []

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

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

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

@@ -182,7 +182,7 @@ def admin_operation(oi_handle, c_invocat

 def abort_ccb(oi_handle, ccb_id):

     ''' Callback for aborted CCBs.



-        Removes the given CCB from the cache

+        Removes the given CCB from the cache.

     '''



     del ccbs[ccb_id]

@@ -223,40 +223,26 @@ def attr_update(oi_handle, c_name, c_att

     class_name = immoi.get_class_name_for_dn(name)



     # Get the values from the user and report back

-    if implementer_instance.on_runtime_values_get:

+    attributes = {}



-        attr_mods = []

+    for attr_name in attr_names:

+        values = implementer_instance.on_runtime_values_get(name, class_name,

+                                                            attr_name)



-        for attr_name in attr_names:

-            values = implementer_instance.on_runtime_values_get(name,

-                                                                class_name,

-                                                                attr_name)

+        if values is None:

+            return eSaAisErrorT.SA_AIS_ERR_UNAVAILABLE



-            if values is None:

-                return eSaAisErrorT.SA_AIS_ERR_UNAVAILABLE

+        if not isinstance(values, list):

+            values = [values]



-            if not isinstance(values, list):

-                values = [values]

+        attributes[attr_name] = values



-            attribute_type = immoi.get_attribute_type(attr_name, class_name)

-

-            attr_mod = saImm.SaImmAttrModificationT_2()

-            attr_mod.modType = 
eSaImmAttrModificationTypeT.SA_IMM_ATTR_VALUES_REPLACE

-            attr_mod.modAttr = saImm.SaImmAttrValuesT_2()

-            attr_mod.modAttr.attrName = saImm.SaImmAttrNameT(attr_name)

-            attr_mod.modAttr.attrValueType = attribute_type

-            attr_mod.modAttr.attrValuesNumber = len(values)

-            attr_mod.modAttr.attrValues = marshal_c_array(attribute_type, 
values)

-            attr_mods = [attr_mod]

-

-        # Report the updated values for the attributes

-        try:

-            immoi.update_rt_object(name, attr_mods)

-        except SafException as err:

-            return eSaAisErrorT.SA_AIS_ERR_FAILED_OPERATION

-

-    else:

-        return eSaAisErrorT.SA_AIS_ERR_NOT_SUPPORTED

+    # Report the updated values for the attributes

+    try:

+        immoi.update_rt_object(name, attributes)

+        return eSaAisErrorT.SA_AIS_OK

+    except SafException as err:

+        return eSaAisErrorT.SA_AIS_ERR_FAILED_OPERATION



 def delete_added(oi_handle, ccb_id, c_name):

     ''' Callback for object delete '''

@@ -353,13 +339,10 @@ def create_added(oi_handle, c_ccb_id, c_

     description = immom.class_description_get(class_name)



     for attribute in description:

-        print attribute.attrName

+

         if not attribute.attrName in attributes:

-            print "Not in attributes, adding"

             attributes[attribute.attrName] = None



-    print attributes

-

     # Create a new CCB in the cache if needed

     if not ccb_id in ccbs.keys():

         ccbs[ccb_id] = []

@@ -619,6 +602,19 @@ class Implementer:

         ''' Sets the admin operations to be executed by the OI '''

         self.admin_operations = admin_operations



+    def on_runtime_values_get(self, name, class_name, attribute_name):

+        ''' Retrieves values for the requested attribute in the given

+            instance

+        '''

+

+        if self.on_runtime_values_get_cb:

+            try:

+                return self.on_runtime_values_get_cb(name, class_name, 
attribute_name)

+            except SafException as err:

+                return err.value

+        else:

+            return None

+

     def on_modify_added(self, attribute_name, modification_type, values):

         ''' Called when an object modify operation has been added to an

             ongoing CCB.

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

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

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

@@ -80,9 +80,14 @@ def _initialize():

     err = saImmOmAccessorInitialize(HANDLE, ACCESSOR_HANDLE)





-def get(object_name, attr_name_list=None):

+def get(object_name, attr_name_list=None, class_name=None):

     ''' obtain values of some attributes of the specified object '''



+    # Always request the SaImmAttrClassName attribute if needed

+    if attr_name_list and not class_name and \

+       not 'SaImmAttrClassName' in attr_name_list:

+        attr_name_list.append('SaImmAttrClassName')

+

     attrib_names = [SaImmAttrNameT(a) for a in attr_name_list]\

         if attr_name_list else None



@@ -109,6 +114,9 @@ def get(object_name, attr_name_list=None

                 attr.attrValueType) for val in attr_range]

             ]



+    if not 'SaImmAttrClassName' in attribs and class_name:

+        attribs['SaImmAttrClassName'] = class_name

+

     return ImmObject(object_name, attribs)



 # initialize handles needed when module is loaded

diff --git a/python/samples/immoi/samples/classes.xml 
b/python/samples/immoi/samples/classes.xml

--- a/python/samples/immoi/samples/classes.xml

+++ b/python/samples/immoi/samples/classes.xml

@@ -25,6 +25,21 @@

     </attr>

   </class>



+  <class name="UsersSampleClass">

+    <category>SA_RUNTIME</category>

+    <rdn>

+      <name>usersId</name>

+      <type>SA_STRING_T</type>

+      <category>SA_RUNTIME</category>

+      <flag>SA_CACHED</flag>

+    </rdn>

+    <attr>

+      <name>users</name>

+      <type>SA_STRING_T</type>

+      <category>SA_RUNTIME</category>

+    </attr>

+  </class>

+

   <!-- Tones OI -->

   <class name="Do">

     <category>SA_CONFIG</category>

diff --git a/python/samples/immoi/samples/users 
b/python/samples/immoi/samples/users

new file mode 100755

--- /dev/null

+++ b/python/samples/immoi/samples/users

@@ -0,0 +1,30 @@

+#!/usr/bin/env python

+

+from pyosaf import saAis

+from pyosaf.utils import immom, immoi, SafException

+from pyosaf.utils.immom.object import ImmObject

+from pyosaf.utils.immoi.implementer import Implementer

+

+import psutil

+

+class_name='UsersSampleClass'

+

+def on_attribute_update(*args):

+    return list(set(map(lambda x: x.name, psutil.get_users())))

+

+if __name__ == '__main__':

+

+    users_implementer = Implementer(on_runtime_values_get=on_attribute_update,

+                                    name='UsersImplementer')

+

+    try:

+        obj = ImmObject(class_name=class_name, dn='usersId=1')

+

+        obj.usersId = 'usersId=1'

+

+        users_implementer.create(obj)

+    except SafException as err:

+        if not err.value == saAis.eSaAisErrorT.SA_AIS_ERR_EXIST:

+            raise err

+

+    users_implementer.enter_dispatch_loop()

diff --git a/python/samples/immoi/samples/users-inheritance-impl 
b/python/samples/immoi/samples/users-inheritance-impl

new file mode 100755

--- /dev/null

+++ b/python/samples/immoi/samples/users-inheritance-impl

@@ -0,0 +1,34 @@

+#!/usr/bin/env python

+

+from pyosaf import saAis

+from pyosaf.utils import immom, immoi, SafException

+from pyosaf.utils.immom.object import ImmObject

+from pyosaf.utils.immoi.implementer import Implementer

+

+import psutil

+

+class_name='UsersSampleClass'

+

+class UsersImplementer(Implementer):

+

+    def __init__(self):

+        Implementer.__init__(self, name='UsersImplementer')

+

+    def on_runtime_values_get(self, name, class_name, attribute):

+        return list(set(map(lambda x: x.name, psutil.get_users())))

+

+if __name__ == '__main__':

+

+    users_implementer = UsersImplementer()

+

+    try:

+        obj = ImmObject(class_name=class_name, dn='usersId=2')

+

+        obj.usersId = 'usersId=2'

+

+        users_implementer.create(obj)

+    except SafException as err:

+        if not err.value == saAis.eSaAisErrorT.SA_AIS_ERR_EXIST:

+            raise err

+

+    users_implementer.enter_dispatch_loop()

------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to