Hi Hung,

Reviewed and tested the patch.
Ack from me.

Best regards,
Zoran

-----Original Message-----
From: Hung Nguyen [mailto:hung.d.ngu...@dektech.com.au] 
Sent: Wednesday, December 23, 2015 10:12 AM
To: Zoran Milinkovic; reddy.neelaka...@oracle.com
Cc: opensaf-devel@lists.sourceforge.net
Subject: [PATCH 1 of 1] imm: Canonicalize attributes presented by 
OiCcbObjectModifyCallback [#801]

 osaf/services/saf/immsv/immnd/ImmModel.cc        |  100 +++++++++++++++++++++++
 osaf/services/saf/immsv/immnd/ImmModel.hh        |    7 +
 osaf/services/saf/immsv/immnd/immnd_evt.c        |   49 +++++++++-
 osaf/services/saf/immsv/immnd/immnd_init.h       |    2 +
 osaf/services/saf/immsv/immpbed/immpbe_daemon.cc |    4 +
 5 files changed, 155 insertions(+), 7 deletions(-)


If the modType is SA_IMM_ATTR_VALUES_ADD or SA_IMM_ATTR_VALUES_DELETE,
it will be converted to SA_IMM_ATTR_VALUES_REPLACE and the values of the 
attr-mod will be the values in the after image.

This feature is only for OIs with version A.2.17 or later so we don't modify 
the content of incoming IMMND_EVT_A2ND_OBJ_MODIFY messages.
New memory is allocated for canonicalized attribute-modifications instead.

PBE will also receive canonicalized attMods.

OIs and appliers which are initialized as A.2.17 or later MUST support 
SA_IMM_ATTR_VALUES_REPLACE in their callbacks.

diff --git a/osaf/services/saf/immsv/immnd/ImmModel.cc 
b/osaf/services/saf/immsv/immnd/ImmModel.cc
--- a/osaf/services/saf/immsv/immnd/ImmModel.cc
+++ b/osaf/services/saf/immsv/immnd/ImmModel.cc
@@ -717,6 +717,11 @@ immModel_genSpecialModify(IMMND_CB *cb, 
         genSpecialModify(req);
 }
 
+struct immsv_attr_mods_list*
+immModel_canonicalizeAttrModification(IMMND_CB *cb, const struct 
ImmsvOmCcbObjectModify *req)
+{
+    return 
ImmModel::instance(&cb->immModel)->canonicalizeAttrModification(req);
+}
 
 SaUint32T
 immModel_getLocalAppliersForObj(IMMND_CB *cb,
@@ -6997,6 +7002,101 @@ ImmModel::specialApplierTrimCreate(SaUin
     return attrValues;
 }
 
+/* This function converts value(s) of an attribute into a single attr-mod.
+ * attrModType is always SA_IMM_ATTR_VALUES_REPLACE.
+ */
+immsv_attr_mods_list*
+ImmModel::attrValueToAttrMod(const ObjectInfo* obj, const std::string& 
attrName,
+                             SaUint32T attrType)
+{
+    ImmAttrValueMap::const_iterator avi = obj->mAttrValueMap.find(attrName);
+    osafassert(avi != obj->mAttrValueMap.end());
+    ImmAttrValue* attrValue = avi->second;
+
+    immsv_attr_mods_list* attrMod = (immsv_attr_mods_list*) calloc(1, 
sizeof(immsv_attr_mods_list));
+    osafassert(attrMod);
+    attrMod->attrModType = SA_IMM_ATTR_VALUES_REPLACE;
+
+    /* attrValue.attrValueType */
+    attrMod->attrValue.attrValueType = attrType;
+
+    /* attrValue.attrName */
+    attrMod->attrValue.attrName.size = strlen(attrName.c_str()) + 1;
+    attrMod->attrValue.attrName.buf = (char*) 
malloc(attrMod->attrValue.attrName.size);
+    osafassert(attrMod->attrValue.attrName.buf);
+    strncpy(attrMod->attrValue.attrName.buf, attrName.c_str(), 
attrMod->attrValue.attrName.size);
+
+    /* attrValue.attrValuesNumber, attrValue.attrValue and 
attrValue.attrMoreValues */
+    attrMod->attrValue.attrValuesNumber = 0;
+    if (!attrValue->empty()) {
+        attrValue->copyValueToEdu(&(attrMod->attrValue.attrValue), 
(SaImmValueTypeT) attrType);
+        if (attrValue->extraValues()) {
+            ImmAttrMultiValue* multiVal = (ImmAttrMultiValue *) attrValue;
+            
multiVal->copyExtraValuesToEdu(&(attrMod->attrValue.attrMoreValues), 
(SaImmValueTypeT) attrType);
+        }
+        attrMod->attrValue.attrValuesNumber = 1 + attrValue->extraValues();
+    } /* else, attrValuesNumber is already set to 0 */
+
+    return attrMod;
+}
+
+/* This function allocates new memory for canonicalized 
attribute-modifications.
+ * The 'attrMods' of input ImmsvOmCcbObjectModify remains untouched.
+ * Remember to free the memory with immsv_free_attrmods().
+ */
+immsv_attr_mods_list*
+ImmModel::canonicalizeAttrModification(const ImmsvOmCcbObjectModify *req)
+{
+    TRACE_ENTER();
+    immsv_attr_mods_list* result = NULL;
+    std::string objectName;
+    CcbVector::iterator ci;
+    CcbInfo* ccb = NULL;
+    ObjectInfo* afim = NULL;
+    ObjectMutationMap::iterator omuti;
+    ObjectMutation* oMut = NULL;
+
+    /* Get object Name */
+    size_t sz = strnlen(req->objectName.buf, (size_t) req->objectName.size);
+    objectName.append((const char*) req->objectName.buf, sz);
+    osafassert(!objectName.empty());
+
+    /* Get ccb info */
+    ci = std::find_if(sCcbVector.begin(), sCcbVector.end(), 
CcbIdIs(req->ccbId));
+    osafassert(ci != sCcbVector.end());
+    ccb = *ci;
+
+    /* Get object mutation */
+    omuti = ccb->mMutations.find(objectName);
+    osafassert(omuti != ccb->mMutations.end());
+    oMut = omuti->second;
+
+    /* Get after image */
+    osafassert(oMut->mOpType != IMM_DELETE);
+    if (oMut->mOpType == IMM_CREATE) { /* Chained operation */
+        ObjectMap::iterator oi = sObjectMap.find(objectName);
+        osafassert(oi != sObjectMap.end());
+        afim = oi->second;
+    } else if (oMut->mOpType == IMM_MODIFY) {
+        afim = oMut->mAfterImage;
+    }
+
+    /* Build canonicalized attr-mod list */
+    immsv_attr_mods_list* reqAttrMods = req->attrMods;
+    for (; reqAttrMods; reqAttrMods = reqAttrMods->next) {
+        size_t sz = strnlen(reqAttrMods->attrValue.attrName.buf,
+                            (size_t) reqAttrMods->attrValue.attrName.size);
+        std::string attrName((const char *) 
reqAttrMods->attrValue.attrName.buf, sz);
+        immsv_attr_mods_list* attrMod = attrValueToAttrMod(afim, attrName,
+                                                           
reqAttrMods->attrValue.attrValueType);
+        attrMod->next = result;
+        result = attrMod;
+    }
+
+    TRACE_LEAVE();
+    return result;
+}
+
 /** 
  * Creates an object
  */
diff --git a/osaf/services/saf/immsv/immnd/ImmModel.hh 
b/osaf/services/saf/immsv/immnd/ImmModel.hh
--- a/osaf/services/saf/immsv/immnd/ImmModel.hh
+++ b/osaf/services/saf/immsv/immnd/ImmModel.hh
@@ -239,6 +239,9 @@ public:
                                        SaUint32T ccbId,
                                         ConnVector& connVector,
                                        SaUint32T* appCtnPtr);
+
+    immsv_attr_mods_list* canonicalizeAttrModification(
+            const struct ImmsvOmCcbObjectModify *req);
     
     SaAisErrorT         ccbObjectModify(
                                         const ImmsvOmCcbObjectModify* req,
@@ -709,6 +712,10 @@ private:
                             ObjectInfo *obj,
                             const char *noDanglingRef);
 
+    immsv_attr_mods_list* attrValueToAttrMod(const ObjectInfo* obj,
+                                             const std::string& attrName,
+                                             SaUint32T attrType);
+
 };
 
 #endif
diff --git a/osaf/services/saf/immsv/immnd/immnd_evt.c 
b/osaf/services/saf/immsv/immnd/immnd_evt.c
--- a/osaf/services/saf/immsv/immnd/immnd_evt.c
+++ b/osaf/services/saf/immsv/immnd/immnd_evt.c
@@ -6212,6 +6212,8 @@ static void immnd_evt_proc_object_modify
        SaNameT objName;
        osaf_extended_name_clear(&objName);
        bool hasLongDns=false;
+       IMMSV_ATTR_MODS_LIST* canonicalizedAttrMod = NULL;
+
        TRACE_ENTER();
 #if 0                          /*ABT DEBUG PRINTOUTS START */
        TRACE_2("ABT immnd_evt_proc_object_modify object:%s", 
evt->info.objModify.objectName.buf);
@@ -6271,6 +6273,8 @@ static void immnd_evt_proc_object_modify
                        /* PBE is internal => can handle long DNs */
                        send_evt.info.imma.type = 
IMMA_EVT_ND2A_OI_OBJ_MODIFY_UC;
                        send_evt.info.imma.info.objModify = evt->info.objModify;
+                       canonicalizedAttrMod = 
immModel_canonicalizeAttrModification(cb, &(evt->info.objModify));
+                       send_evt.info.imma.info.objModify.attrMods = 
canonicalizedAttrMod;
                        send_evt.info.imma.info.objModify.adminOwnerId = 0; 
                        /*We re-use the adminOwner member of the ccbModify 
message to hold the 
                          invocation id. In this case, 0 => no reply is 
expected. */
@@ -6317,6 +6321,17 @@ static void immnd_evt_proc_object_modify
                                        IMMA_EVT_ND2A_OI_OBJ_MODIFY_LONG_UC : 
IMMA_EVT_ND2A_OI_OBJ_MODIFY_UC;
 
                                send_evt.info.imma.info.objModify = 
evt->info.objModify;
+
+                               /* For A.2.17 or later */
+                               if (oi_cl_node->version.minorVersion >= 0x11 &&
+                                               
oi_cl_node->version.majorVersion == 0x2 &&
+                                               oi_cl_node->version.releaseCode 
== 'A') {
+                                       if (!canonicalizedAttrMod) { /* Check 
if canonicalizedAttrMod is already built */
+                                               canonicalizedAttrMod = 
immModel_canonicalizeAttrModification(cb, &(evt->info.objModify));
+                                       }
+                                       
send_evt.info.imma.info.objModify.attrMods = canonicalizedAttrMod;
+                               }
+
                                /* shallow copy into stack alocated structure. 
*/
 
                                send_evt.info.imma.info.objModify.adminOwnerId 
= continuationId;
@@ -6358,6 +6373,8 @@ static void immnd_evt_proc_object_modify
                          invocation id. In this case, 0 => no reply is 
expected. */
 
                        for (; ix < arrSize && err == SA_AIS_OK; ++ix) {
+                               bool isSpecialApplier = false;
+                               send_evt.info.imma.info.objModify.attrMods = 
evt->info.objModify.attrMods;
                                implHandle = 
m_IMMSV_PACK_HANDLE(applConnArr[ix], cb->node_id);
                                send_evt.info.imma.info.objModify.immHandle = 
implHandle;
 
@@ -6367,14 +6384,35 @@ static void immnd_evt_proc_object_modify
                                            If not special applier, then 
attribute-list will be untouched
                                           since the last applier is then a 
regular applier. 
                                         */
-                                       evt->info.objModify.attrMods = 
send_evt.info.imma.info.objModify.attrMods =
+                                       
send_evt.info.imma.info.objModify.attrMods =
                                                
immModel_specialApplierTrimModify(cb, applConnArr[ix], &(evt->info.objModify));
 
+                                       /* If attrMods of 'send_evt' is 
different from attrMods of 'evt'
+                                        * then we are sending to the special 
applier. */
+                                       if 
(send_evt.info.imma.info.objModify.attrMods != evt->info.objModify.attrMods) {
+                                               isSpecialApplier = true;
+                                               evt->info.objModify.attrMods = 
send_evt.info.imma.info.objModify.attrMods;
+                                       }
                                }
 
                                /*Fetch client node for Applier OI ! */
                                immnd_client_node_get(cb, implHandle, 
&oi_cl_node);
                                osafassert(oi_cl_node != NULL);
+
+                               /* For A.2.17 or later */
+                               if (!isSpecialApplier &&
+                                               
oi_cl_node->version.minorVersion >= 0x11 &&
+                                               
oi_cl_node->version.majorVersion == 0x2 &&
+                                               oi_cl_node->version.releaseCode 
== 'A') {
+                                       if (!canonicalizedAttrMod) { /* Check 
if canonicalizedAttrMod is already built */
+                                               canonicalizedAttrMod = 
immModel_canonicalizeAttrModification(cb, &(evt->info.objModify));
+                                       }
+                                       
send_evt.info.imma.info.objModify.attrMods = canonicalizedAttrMod;
+                               }
+                               /* Slave pbe is initialized with latest OI api 
version,
+                                * it will also receive canonicalized attrMod 
like the primary pbe
+                                */
+
                                if (oi_cl_node->mIsStale) {
                                        LOG_WA("Applier client went down so 
modify upcall not sent");
                                        continue;
@@ -6416,12 +6454,9 @@ static void immnd_evt_proc_object_modify
        }
 
  done:
-       /*Free the incomming events substructure. */
-       free(evt->info.objModify.objectName.buf);
-       evt->info.objModify.objectName.buf = NULL;
-       evt->info.objModify.objectName.size = 0;
-       immsv_free_attrmods(evt->info.objModify.attrMods);
-       evt->info.objModify.attrMods = NULL;
+       /* Free the canonicalized attr mods */
+       immsv_free_attrmods(canonicalizedAttrMod);
+       canonicalizedAttrMod = NULL;
        osaf_extended_name_free(&objName);
        TRACE_LEAVE();
 }
diff --git a/osaf/services/saf/immsv/immnd/immnd_init.h 
b/osaf/services/saf/immsv/immnd/immnd_init.h
--- a/osaf/services/saf/immsv/immnd/immnd_init.h
+++ b/osaf/services/saf/immsv/immnd/immnd_init.h
@@ -296,6 +296,8 @@ extern "C" {
 
        void immModel_genSpecialModify(IMMND_CB *cb, struct 
ImmsvOmCcbObjectModify *req);
 
+       struct immsv_attr_mods_list*
+       immModel_canonicalizeAttrModification(IMMND_CB *cb, const struct 
ImmsvOmCcbObjectModify *req);
 
        SaBoolT immModel_protocol41Allowed(IMMND_CB *cb);
        SaBoolT immModel_protocol43Allowed(IMMND_CB *cb);
diff --git a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc 
b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
--- a/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
+++ b/osaf/services/saf/immsv/immpbed/immpbe_daemon.cc
@@ -136,6 +136,10 @@ static SaAisErrorT sqlite_prepare_ccb(Sa
                                TRACE("Modify of object with DN: %s",
                                        
osaf_extended_name_borrow(ccbUtilOperationData->param.modify.objectName));
 
+                               /* Pbe receives canonicalized attrMod for 
config-object modifications (CCB)
+                                * but it still receive normal attrMod for 
runtime-object modifications (updating PRTA).
+                                * So we have to support all kinds of 
SaImmAttrModificationTypeT here.
+                                */
                                
objName.append(osaf_extended_name_borrow(ccbUtilOperationData->
                                        param.modify.objectName));
                                attrMods = 
ccbUtilOperationData->param.modify.attrMods;

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to