See inline and please comment.
/HansF

> -----Original Message-----
> From: Nagendra Kumar [mailto:nagendr...@oracle.com]
> Sent: den 28 maj 2014 12:13
> To: Hans Nordebäck; Hans Feldt; Praveen Malviya
> Cc: opensaf-devel@lists.sourceforge.net
> Subject: RE: [PATCH 1 of 1] AMF: Use IMM applier in the AMF node director V3 
> [#819]
> 
> I have few concerns:
> 
> 1.    It has severe performance issues(when number of nodes increases with 
> configurations) as we had discussed in #517
> patch(Sent on 2 Sep 2013).
[Hans] I don't understand. This change actually reduces cluster impact during 
change. The AMF director validates and lets IMM distribute the change.

517 is something else. The relation to this patch is that handling of BADHANDLE 
needs to be added. I have looked at 517 an my conclusion is that amfnd needs a 
helper thread to read from IMM. That thread can block and reinitialize with IMM.

> 2.    Due to syncing between directors and node directors(when complete 
> configuration of sg is loaded at one go), there may be
> issues like #926,
>       because directors will send su/comp information to amfnd and amfnd will 
> also get it from immnd as applier.
[Hans] well I guess the idea as to only handle modifications of existing 
already used objects. How can something similar like 926 happen to amfnd you 
mean?

> 3.    It has lots of code duplicity and maintenance.
[Hans] that could be true as I have already pointed out.

> 
> Thanks
> -Nagu
> 
> > -----Original Message-----
> > From: Hans Nordeback [mailto:hans.nordeb...@ericsson.com]
> > Sent: 28 May 2014 14:27
> > To: hans.fe...@ericsson.com; Nagendra Kumar; Praveen Malviya
> > Cc: opensaf-devel@lists.sourceforge.net
> > Subject: [PATCH 1 of 1] AMF: Use IMM applier in the AMF node director V3
> > [#819]
> >
> >  osaf/libs/common/amf/include/amf_defs.h         |    6 +
> >  osaf/services/saf/amf/amfnd/Makefile.am         |    1 +
> >  osaf/services/saf/amf/amfnd/evt.cc              |    7 +
> >  osaf/services/saf/amf/amfnd/hcdb.cc             |  150 ++++
> >  osaf/services/saf/amf/amfnd/imm.cc              |  758
> > ++++++++++++++++++++++++
> >  osaf/services/saf/amf/amfnd/include/Makefile.am |    1 +
> >  osaf/services/saf/amf/amfnd/include/avnd.h      |    1 +
> >  osaf/services/saf/amf/amfnd/include/avnd_evt.h  |    8 +
> >  osaf/services/saf/amf/amfnd/include/avnd_hc.h   |    1 +
> >  osaf/services/saf/amf/amfnd/include/avnd_imm.h  |  148 ++++
> >  osaf/services/saf/amf/amfnd/main.cc             |   10 +-
> >  11 files changed, 1090 insertions(+), 1 deletions(-)
> >
> >
> > This first patch adds support for changing attributes in class
> > SaAmfHealthcheckType
> > Updated with review comments.
> >
> > diff --git a/osaf/libs/common/amf/include/amf_defs.h
> > b/osaf/libs/common/amf/include/amf_defs.h
> > --- a/osaf/libs/common/amf/include/amf_defs.h
> > +++ b/osaf/libs/common/amf/include/amf_defs.h
> > @@ -254,6 +254,12 @@ typedef enum
> >     saAmfHealthcheckMaxDuration_ID = 2,
> >  } AVSV_AMF_HEALTHCHECK_ATTR_ID;
> >
> > +/* Attribute ID enum for the SaAmfHealthcheckType class */
> > +typedef enum
> > +{
> > +   saAmfHctDefPeriod_ID = 1,
> > +   saAmfHctDefMaxDuration_ID = 2,
> > +} AMF_HEALTHCHECK_TYPE_ATTR_ID;
> >
> >  #define AVSV_COMMON_SUB_ID_DEFAULT_VAL 1
> >  #define SA_AMF_PRESENCE_ORPHANED
> > (SA_AMF_PRESENCE_TERMINATION_FAILED+1)
> > diff --git a/osaf/services/saf/amf/amfnd/Makefile.am
> > b/osaf/services/saf/amf/amfnd/Makefile.am
> > --- a/osaf/services/saf/amf/amfnd/Makefile.am
> > +++ b/osaf/services/saf/amf/amfnd/Makefile.am
> > @@ -51,6 +51,7 @@ osafamfnd_SOURCES = \
> >     err.cc \
> >     evt.cc \
> >     hcdb.cc \
> > +   imm.cc \
> >     main.cc \
> >     mbcsv.cc \
> >     mds.cc \
> > diff --git a/osaf/services/saf/amf/amfnd/evt.cc
> > b/osaf/services/saf/amf/amfnd/evt.cc
> > --- a/osaf/services/saf/amf/amfnd/evt.cc
> > +++ b/osaf/services/saf/amf/amfnd/evt.cc
> > @@ -32,6 +32,7 @@
> >  */
> >
> >  #include "avnd.h"
> > +#include "avnd_imm.h"
> >
> >
> > /************************************************************
> > ****************
> >    Name          : avnd_evt_create
> > @@ -200,6 +201,7 @@ AVND_EVT *avnd_evt_create(AVND_CB *cb,
> >  void avnd_evt_destroy(AVND_EVT *evt)
> >  {
> >     uint32_t type = 0;
> > +   AvndImmEvt *imm = 0;
> >
> >     if (!evt)
> >             return;
> > @@ -294,6 +296,11 @@ void avnd_evt_destroy(AVND_EVT *evt)
> >     case AVND_EVT_PID_EXIT:
> >             break;
> >
> > +   case AVND_EVT_IMM:
> > +           imm = static_cast<AvndImmEvt*>(evt->info.imm.imm_evt);
> > +           delete imm;
> > +           break;
> > +
> >     default:
> >             LOG_NO("%s: unknown event type %u", __FUNCTION__,
> > type);
> >             break;
> > diff --git a/osaf/services/saf/amf/amfnd/hcdb.cc
> > b/osaf/services/saf/amf/amfnd/hcdb.cc
> > --- a/osaf/services/saf/amf/amfnd/hcdb.cc
> > +++ b/osaf/services/saf/amf/amfnd/hcdb.cc
> > @@ -36,6 +36,7 @@
> >  #include "avnd.h"
> >  #include <saImmOm.h>
> >  #include <immutil.h>
> > +#include <string>
> >
> >  static NCS_PATRICIA_TREE hctypedb; /* healthcheck type db */
> >
> > @@ -339,6 +340,93 @@ SaAisErrorT avnd_hctype_config_get(SaImm
> >     return error;
> >  }
> >
> > +// Search for a given key and return its value  or empty string if not 
> > found.
> > +static std::string search_key(const std::string& str, const std::string& 
> > key)
> > +{
> > +   std::string value;
> > +
> > +   std::string::size_type idx1;
> > +
> > +   idx1 = str.find(key);
> > +
> > +   // if key was found
> > +   if (idx1 != std::string::npos) {
> > +           // get value, idx2 points to value
> > +           idx1 += key.length();
> > +           std::string part2 = str.substr(idx1);
> > +
> > +           idx1 = part2.find(",");
> > +
> > +           // get value
> > +           value = part2.substr(0, idx1);
> > +   }
> > +
> > +   return value;
> > +}
> > +
> > +//
> > +static void comp_hctype_update_compdb(AVND_CB *cb,
> > AVSV_PARAM_INFO *param)
> > +{
> > +   AVND_COMP_HC_REC *comp_hc_rec;
> > +   AVND_COMP * comp;
> > +   char *comp_type_name;
> > +   AVSV_HLT_KEY hlt_chk;
> > +   AVND_COMP_HC_REC tmp_hc_rec;
> > +
> > +   // 1. find component from componentType,
> > +   // input example, param->name.value =
> > safHealthcheckKey=AmfDemo,safVersion=1,safCompType=AmfDemo1
> > +   comp_type_name = strstr((char *) param->name.value, "safVersion");
> > +   TRACE("comp_type_name: %s", comp_type_name);
> > +   osafassert(comp_type_name);
> > +
> > +   // 2. search each component for a matching compType
> > +   comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb->compdb,
> > (uint8_t *) 0);
> > +   while (comp != 0) {
> > +           if (strncmp((const char*) comp->saAmfCompType.value,
> > comp_type_name, comp->saAmfCompType.length) == 0) {
> > +
> > +                   // 3. matching compType found, check that component
> > does not have a SaAmfHealthcheck rec (specialization)
> > +                   std::string hlt_chk_key = search_key((const char*)
> > param->name.value, "safHealthcheckKey=");
> > +                   if (hlt_chk_key.empty()) {
> > +                           LOG_ER("%s: failed to get healthcheckKey
> > from %s", __FUNCTION__, param->name.value);
> > +                           return;
> > +                   }
> > +
> > +                   memset(&hlt_chk, 0, sizeof(AVSV_HLT_KEY));
> > +                   hlt_chk.comp_name.length = comp->name.length;
> > +                   memcpy(hlt_chk.comp_name.value, comp-
> > >name.value, hlt_chk.comp_name.length);
> > +                   hlt_chk.key_len = hlt_chk_key.size();
> > +                   memcpy(hlt_chk.name.key, hlt_chk_key.c_str(),
> > hlt_chk_key.size());
> > +                   hlt_chk.name.keyLen = hlt_chk.key_len;
> > +                   TRACE("comp_name %s key %s keyLen %u",
> > hlt_chk.comp_name.value, hlt_chk.name.key, hlt_chk.name.keyLen);
> > +                   if (avnd_hcdb_rec_get(cb, &hlt_chk) == 0) {
> > +                           TRACE("comp uses healthcheckType rec");
> > +                           // 4. found a component that uses the
> > healthcheckType record, update the comp_hc_rec
> > +                           memset(&tmp_hc_rec, '\0',
> > sizeof(AVND_COMP_HC_REC));
> > +                           tmp_hc_rec.key = hlt_chk.name;
> > +                           tmp_hc_rec.req_hdl = comp->reg_hdl;
> > +                           TRACE("tmp_hc_rec: key %s req_hdl %llu",
> > tmp_hc_rec.key.key, tmp_hc_rec.req_hdl);
> > +                           if ((comp_hc_rec =
> > m_AVND_COMPDB_REC_HC_GET(*comp, tmp_hc_rec)) != 0) {
> > +                                   TRACE("comp_hc_rec: period %llu
> > max_dur %llu", comp_hc_rec->period, comp_hc_rec->max_dur);
> > +                                   switch (param->attr_id) {
> > +                                   case saAmfHctDefPeriod_ID:
> > +                                           comp_hc_rec->period =
> > *((SaTimeT *) param->value);
> > +                                           LOG_NO("%s:
> > saAmfHctDefPeriod updated, new value: %" PRIu64, __FUNCTION__,
> > (uint64_t) comp_hc_rec->period);
> > +                                           break;
> > +                                   case saAmfHctDefMaxDuration_ID:
> > +                                           comp_hc_rec->max_dur =
> > *((SaTimeT *) param->value);
> > +                                           LOG_NO("%s:
> > saAmfHctDefMaxDuration updated, new value: %" PRIu64, __FUNCTION__,
> > (uint64_t) comp_hc_rec->max_dur);
> > +                                           break;
> > +                                   default:
> > +                                           osafassert(0);
> > +                                   }
> > +                           }
> > +                   }
> > +           }
> > +           comp = (AVND_COMP *) ncs_patricia_tree_getnext(&cb-
> > >compdb, (uint8_t *) & comp->name);
> > +   }
> > +}
> > +
> > +//
> >  uint32_t avnd_hc_oper_req(AVND_CB *cb, AVSV_PARAM_INFO *param)
> >  {
> >     uint32_t rc = NCSCC_RC_FAILURE;
> > @@ -401,3 +489,65 @@ done:
> >     return rc;
> >  }
> >
> > +uint32_t avnd_hctype_oper_req(AVND_CB *cb, AVSV_PARAM_INFO
> > *param)
> > +{
> > +   uint32_t rc = NCSCC_RC_FAILURE;
> > +
> > +   TRACE_ENTER2("'%s'", param->name.value);
> > +   AVND_HCTYPE *hctype = (AVND_HCTYPE *)
> > ncs_patricia_tree_get(&hctypedb, (uint8_t *)&param->name);
> > +
> > +   switch (param->act) {
> > +   case AVSV_OBJ_OPR_MOD: {
> > +           if (!hctype) {
> > +                   LOG_ER("%s: failed to get %s", __FUNCTION__,
> > param->name.value);
> > +                   goto done;
> > +           }
> > +
> > +           switch (param->attr_id) {
> > +           case saAmfHctDefPeriod_ID:
> > +                   osafassert(sizeof(SaTimeT) == param->value_len);
> > +                   hctype->saAmfHctDefPeriod = *((SaTimeT *)param-
> > >value);
> > +                   comp_hctype_update_compdb(cb, param);
> > +                   break;
> > +
> > +           case saAmfHctDefMaxDuration_ID:
> > +                   osafassert(sizeof(SaTimeT) == param->value_len);
> > +                   hctype->saAmfHctDefMaxDuration = *((SaTimeT
> > *)param->value);
> > +                   comp_hctype_update_compdb(cb, param);
> > +                   break;
> > +
> > +           default:
> > +                   LOG_NO("%s: Unsupported attribute %u",
> > __FUNCTION__, param->attr_id);
> > +                   goto done;
> > +           }
> > +           break;
> > +   }
> > +
> > +   case AVSV_OBJ_OPR_DEL: {
> > +           if (hctype != NULL) {
> > +                   rc = ncs_patricia_tree_del(&hctypedb, &hctype-
> > >tree_node);
> > +                   osafassert(rc == NCSCC_RC_SUCCESS);
> > +                   LOG_IN("Deleted '%s'", param->name.value);
> > +           } else {
> > +                   /*
> > +                    ** Normal case that happens if a parent of this HC was
> > +                    ** the real delete target for the CCB.
> > +                    */
> > +                        TRACE("already deleted!");
> > +           }
> > +
> > +           break;
> > +   }
> > +   default:
> > +           LOG_NO("%s: Unsupported action %u", __FUNCTION__,
> > param->act);
> > +           goto done;
> > +   }
> > +
> > +   rc = NCSCC_RC_SUCCESS;
> > +
> > +done:
> > +   rc = NCSCC_RC_SUCCESS;
> > +
> > +   TRACE_LEAVE();
> > +   return rc;
> > +}
> > diff --git a/osaf/services/saf/amf/amfnd/imm.cc
> > b/osaf/services/saf/amf/amfnd/imm.cc
> > new file mode 100644
> > --- /dev/null
> > +++ b/osaf/services/saf/amf/amfnd/imm.cc
> > @@ -0,0 +1,758 @@
> > +/*      -*- OpenSAF  -*-
> > + *
> > + * (C) Copyright 2014 The OpenSAF Foundation
> > + *
> > + * This program is distributed in the hope that it will be useful, but
> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
> > MERCHANTABILITY
> > + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> > + * under the GNU Lesser General Public License Version 2.1, February 1999.
> > + * The complete license can be accessed from the following location:
> > + * http://opensource.org/licenses/lgpl-license.php
> > + * See the Copying file included with the OpenSAF distribution for full
> > + * licensing terms.
> > + *
> > + * Author(s): Ericsson AB
> > + *
> > + */
> > +
> > +/***********************************************************
> > ******************
> > +
> > +  DESCRIPTION:
> > +
> > +
> > *************************************************************
> > ***************/
> > +#include <string>
> > +#include <cstring>
> > +#include <algorithm>
> > +#include <poll.h>
> > +#include "avnd_imm.h"
> > +#include "immutil.h"
> > +
> > +extern struct ImmutilWrapperProfile immutilWrapperProfile;
> > +
> > +//
> > +SaVersionT AvndImm::immVersion_ = {'A', 2, 11};
> > +SaImmOiHandleT AvndImm::immOiHandle_ = 0;
> > +SaImmOiHandleT AvndImm::immOmHandle_ = 0;
> > +SaSelectionObjectT AvndImm::imm_sel_obj_ = -1;
> > +AvndImm::UpdateFn
> > AvndImm::update_callback_[AVSV_SA_AMF_CLASS_MAX] = {0};
> > +
> > +// This string array must match the AVND_AMF_CLASS_ID enum
> > +const char *AvndImm::avnd_class_names_[] = {
> > +  "SaAmfHealthcheckType"
> > +};
> > +
> > +/**
> > + * This method adds IMM modification attribute to attribute vector
> > + *
> > + * @param attr
> > + */
> > +void AvndImmEvt::set_mod_attr(const SaImmAttrModificationT_2& attr) {
> > +  SaImmAttrModificationT_2 *tmp = new SaImmAttrModificationT_2;
> > +  tmp->modType = attr.modType;
> > +  AvndImmUtil::copySaImmAttrValuesT(tmp->modAttr, attr.modAttr);
> > +  attr_.push_back(tmp);
> > +}
> > +
> > +
> > +/**
> > + * Destructor
> > + */
> > +AvndImmEvt::~AvndImmEvt() {
> > +  std::for_each(attr_.begin(), attr_.end(), AvndImmUtil::remove_attr);
> > +  attr_.clear();
> > +}
> > +
> > +/**
> > + * This function returns a pointer to a new string which is a duplicate of 
> > the
> > string s.
> > + *
> > + * @param s
> > + *
> > + * @return pointer to new string
> > + */
> > +char *AvndImmUtil::str_dup(const char *s) {
> > +  char *c = new char[strlen(s) + 1];
> > +  std::strcpy(c, s);
> > +  return c;
> > +}
> > +
> > +/**
> > + * This function returns the size of given attribute value type.
> > + *
> > + * @param attrValueType
> > + *
> > + * @return attrValueType size
> > + */
> > +size_t AvndImmUtil::value_size(SaImmValueTypeT attrValueType) {
> > +  size_t value_size = 0;
> > +
> > +  switch (attrValueType) {
> > +    case SA_IMM_ATTR_SAINT32T:
> > +      value_size = sizeof(SaInt32T);
> > +      break;
> > +    case SA_IMM_ATTR_SAUINT32T:
> > +      value_size = sizeof(SaUint32T);
> > +      break;
> > +    case SA_IMM_ATTR_SAINT64T:
> > +      value_size = sizeof(SaInt64T);
> > +      break;
> > +    case SA_IMM_ATTR_SAUINT64T:
> > +      value_size = sizeof(SaUint64T);
> > +      break;
> > +    case SA_IMM_ATTR_SATIMET:
> > +      value_size = sizeof(SaTimeT);
> > +      break;
> > +    case SA_IMM_ATTR_SANAMET:
> > +      value_size = sizeof(SaNameT);
> > +      break;
> > +    case SA_IMM_ATTR_SAFLOATT:
> > +      value_size = sizeof(SaFloatT);
> > +      break;
> > +    case SA_IMM_ATTR_SADOUBLET:
> > +      value_size = sizeof(SaDoubleT);
> > +      break;
> > +    case SA_IMM_ATTR_SASTRINGT:
> > +      value_size = sizeof(SaStringT);
> > +      break;
> > +    case SA_IMM_ATTR_SAANYT:
> > +      osafassert(0);
> > +      break;
> > +  }
> > +
> > +  return value_size;
> > +}
> > +
> > +/**
> > + * This function returns class enum corresponding to object name.
> > + *
> > + * @param obj_name
> > + * @param class_type
> > + *
> > + * @return AVSV_AMF_CLASS_ID
> > + */
> > +AVSV_AMF_CLASS_ID AvndImmUtil::object_name_to_class_type(const
> > SaNameT *obj_name) {
> > +  AVSV_AMF_CLASS_ID class_type = AVSV_SA_AMF_CLASS_INVALID;
> > +
> > +  /* Cluster and Node Class Related */
> > +  if (strncmp((char *)&obj_name->value, "safAmfCluster=", 14) == 0) {
> > +    class_type = AVSV_SA_AMF_CLUSTER;
> > +  } else if (strncmp((char *)&obj_name->value, "safAmfNode=", 11) == 0) {
> > +    class_type = AVSV_SA_AMF_NODE;
> > +  } else if (strncmp((char *)&obj_name->value, "safAmfNodeGroup=", 16) ==
> > 0) {
> > +    class_type = AVSV_SA_AMF_NODE_GROUP;
> > +  } else if (strncmp((char *)&obj_name->value, "safInstalledSwBundle=", 21)
> > == 0) {
> > +    class_type = AVSV_SA_AMF_NODE_SW_BUNDLE;
> > +  }
> > +
> > +  /* Application Class Related */
> > +  else if (strncmp((char *)&obj_name->value, "safApp=", 7) == 0) {
> > +    class_type = AVSV_SA_AMF_APP;
> > +  } else if (strncmp((char *)&obj_name->value, "safAppType=", 11) == 0) {
> > +    class_type = AVSV_SA_AMF_APP_BASE_TYPE;
> > +  }
> > +
> > +  /* Service Group Class Related */
> > +  else if (strncmp((char *)&obj_name->value, "safSg=", 6) == 0) {
> > +    class_type = AVSV_SA_AMF_SG;
> > +  } else if (strncmp((char *)&obj_name->value, "safSgType=", 10) == 0) {
> > +    class_type = AVSV_SA_AMF_SG_BASE_TYPE;
> > +  }
> > +
> > +  /* Service Unit Class Related */
> > +  else if (strncmp((char *)&obj_name->value, "safSu=", 6) == 0) {
> > +    class_type = AVSV_SA_AMF_SU;
> > +  } else if (strncmp((char *)&obj_name->value, "safSuType=", 10) == 0) {
> > +    class_type = AVSV_SA_AMF_SU_BASE_TYPE;
> > +  } else if (strncmp((char *)&obj_name->value, "safMemberCompType=", 18)
> > == 0) {
> > +    class_type = AVSV_SA_AMF_SUT_COMP_TYPE;
> > +  }
> > +
> > +  /* Service Instance Class Related */
> > +  else if (strncmp((char *)&obj_name->value, "safSi=", 6) == 0) {
> > +    class_type = AVSV_SA_AMF_SI;
> > +  } else if (strncmp((char *)&obj_name->value, "safSvcType=", 11) == 0) {
> > +    class_type = AVSV_SA_AMF_SVC_BASE_TYPE;
> > +  } else if (strncmp((char *)&obj_name->value, "safDepend=", 10) == 0) {
> > +    class_type = AVSV_SA_AMF_SI_DEPENDENCY;
> > +  } else if (strncmp((char *)&obj_name->value, "safRankedSu=", 12) == 0) {
> > +    class_type = AVSV_SA_AMF_SI_RANKED_SU;
> > +  } else if (strncmp((char *)&obj_name->value, "safSISU=", 8) == 0) {
> > +    class_type = AVSV_SA_AMF_SI_ASSIGNMENT;
> > +  } else if (strncmp((char *)&obj_name->value, "safMemberCSType=", 16) ==
> > 0) {
> > +    class_type = AVSV_SA_AMF_SVC_TYPE_CS_TYPES;
> > +  }
> > +
> > +  /* Component Service Instance Class Related */
> > +  else if (strncmp((char *)&obj_name->value, "safCsi=", 7) == 0) {
> > +    class_type = AVSV_SA_AMF_CSI;
> > +  } else if (strncmp((char *)&obj_name->value, "safCSType=", 10) == 0) {
> > +    class_type = AVSV_SA_AMF_CS_BASE_TYPE;
> > +  } else if (strncmp((char *)&obj_name->value, "safCsiAttr=", 11) == 0) {
> > +    class_type = AVSV_SA_AMF_CSI_ATTRIBUTE;
> > +  } else if (strncmp((char *)&obj_name->value, "safCSIComp=", 11) == 0) {
> > +    class_type = AVSV_SA_AMF_CSI_ASSIGNMENT;
> > +  }
> > +
> > +  /* Component and component types Related */
> > +  else if (strncmp((char *)&obj_name->value, "safCompType=", 12) == 0) {
> > +    class_type = AVSV_SA_AMF_COMP_BASE_TYPE;
> > +  } else if (strncmp((char *)&obj_name->value, "safSupportedCsType=", 19) 
> > ==
> > 0) {
> > +    if (strstr((char *)&obj_name->value, "safCompType=") != 0) {
> > +      class_type = AVSV_SA_AMF_CT_CS_TYPE;
> > +    } else if (strstr((char *)&obj_name->value, "safComp=") != 0) {
> > +      class_type = AVSV_SA_AMF_COMP_CS_TYPE;
> > +    }
> > +  } else if (strncmp((char *)&obj_name->value, "safComp=", 8) == 0) {
> > +    class_type = AVSV_SA_AMF_COMP;
> > +  }
> > +
> > +  /* Global Component Attributes and Health Check Related */
> > +  else if (strncmp((char *)&obj_name->value, "safRdn=", 7) == 0) {
> > +    class_type = AVSV_SA_AMF_COMP_GLOBAL_ATTR;
> > +  } else if (strncmp((char *)&obj_name->value, "safHealthcheckKey=", 18) ==
> > 0) {
> > +    if (strstr((char *)&obj_name->value, "safVersion=") != 0) {
> > +      class_type = AVSV_SA_AMF_HEALTH_CHECK_TYPE;
> > +    } else if (strstr((char *)&obj_name->value, "safComp=") != 0) {
> > +      class_type = AVSV_SA_AMF_HEALTH_CHECK;
> > +    }
> > +  }
> > +
> > +  /* Common Version Related */
> > +  else if (strncmp((char *)&obj_name->value, "safVersion=", 11) == 0) {
> > +    if (strstr((char *)&obj_name->value, "safAppType=") != 0) {
> > +      class_type = AVSV_SA_AMF_APP_TYPE;
> > +    } else if (strstr((char *)&obj_name->value, "safSgType=") != 0) {
> > +      class_type = AVSV_SA_AMF_SG_TYPE;
> > +    } else if (strstr((char *)&obj_name->value, "safSuType=") != 0) {
> > +      class_type = AVSV_SA_AMF_SU_TYPE;
> > +    } else if (strstr((char *)&obj_name->value, "safSvcType=") != 0) {
> > +      class_type = AVSV_SA_AMF_SVC_TYPE;
> > +    } else if (strstr((char *)&obj_name->value, "safCSType=") != 0) {
> > +      class_type = AVSV_SA_AMF_CS_TYPE;
> > +    } else if (strstr((char *)&obj_name->value, "safCompType=") != 0) {
> > +      class_type = AVSV_SA_AMF_COMP_TYPE;
> > +    }
> > +  }
> > +
> > +  return class_type;
> > +}
> > +
> > +/**
> > + * Delete attribute structures.
> > + *
> > + * @param attr
> > + */
> > +void AvndImmUtil::remove_attr(SaImmAttrModificationT_2* attr) {
> > +  AvndImmUtil::deleteSaImmAttrValuesT(attr->modAttr);
> > +  delete attr;
> > +}
> > +
> > +/**
> > + * Delete attribute values.
> > + *
> > + * @param reference to attrValue
> > + */
> > +void AvndImmUtil::deleteSaImmAttrValuesT(SaImmAttrValuesT_2&
> > attr_value) {
> > +  unsigned int i;
> > +
> > +  if (attr_value.attrValueType == SA_IMM_ATTR_SASTRINGT) {
> > +    for (i = 0; i < attr_value.attrValuesNumber; i++) {
> > +      char *p = *((char**) attr_value.attrValues[i]);
> > +      delete [] p;
> > +    }
> > +  }
> > +
> > +  delete [] attr_value.attrName;
> > +  delete [] static_cast<char*> (attr_value.attrValues[0]); // free blob 
> > shared by
> > all values
> > +  delete [] attr_value.attrValues;
> > +
> > +}
> > +
> > +/**
> > + * Copy IMM attr values,
> > + *
> > + * @param to
> > + * @param from
> > + */
> > +void AvndImmUtil::copySaImmAttrValuesT(SaImmAttrValuesT_2& to, const
> > SaImmAttrValuesT_2& from) {
> > +  size_t val_size = 0;
> > +  unsigned int i;
> > +  unsigned int value_count = from.attrValuesNumber;
> > +  char *databuffer;
> > +
> > +  to.attrName = str_dup(from.attrName);
> > +
> > +  to.attrValuesNumber = value_count;
> > +  to.attrValueType = from.attrValueType;
> > +  if (value_count == 0)
> > +    return; /* (just in case...) */
> > +
> > +  to.attrValues = new SaImmAttrValueT[value_count];
> > +
> > +  val_size = value_size(from.attrValueType);
> > +
> > +  // alloc blob shared by all values
> > +  databuffer = new char[value_count * val_size];
> > +
> > +  for (i = 0; i < value_count; i++) {
> > +    to.attrValues[i] = databuffer;
> > +    if (from.attrValueType == SA_IMM_ATTR_SASTRINGT) {
> > +      char *cporig = *((char **) from.attrValues[i]);
> > +      char **cpp = (char **) databuffer;
> > +      *cpp = str_dup(cporig);
> > +    } else {
> > +      memcpy(databuffer, from.attrValues[i], val_size);
> > +    }
> > +    databuffer += val_size;
> > +  }
> > +}
> > +
> > +/**
> > + * Function called for not implemented callback types.
> > + *
> > + * @param object_name
> > + * @param imm_attr
> > + *
> > + * @return   NCSCC_RC_FAILURE;
> > + */
> > +uint32_t AvndImm::not_yet_implemented(const std::string& object_name,
> > const SaImmAttrModificationT_2* imm_attr) {
> > +  LOG_WA("Not yet implemented");
> > +  return NCSCC_RC_FAILURE;
> > +}
> > +
> > +/**
> > + * Function called for updating health check type.
> > + *
> > + * @param object_name
> > + * @param imm_attr
> > + *
> > + * @return   NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE;
> > + */
> > +uint32_t AvndImm::update_health_check_type(const std::string&
> > object_name, const SaImmAttrModificationT_2* imm_attr) {
> > +  uint32_t rc = NCSCC_RC_FAILURE;
> > +  AVND_CB *cb = avnd_cb;
> > +
> > +  AVSV_PARAM_INFO param;
> > +  memset(&param, 0, sizeof(param));
> > +  param.class_id = AVSV_SA_AMF_HEALTH_CHECK_TYPE;
> > +
> > +  std::string attr_name = imm_attr->modAttr.attrName;
> > +
> > +  strncpy((char*) param.name.value, object_name.c_str(),
> > object_name.size());
> > +  param.name.length = object_name.size();
> > +
> > +  if (attr_name == "saAmfHctDefPeriod") {
> > +    param.attr_id = saAmfHctDefPeriod_ID;
> > +  } else if (attr_name == "saAmfHctDefMaxDuration") {
> > +    param.attr_id = saAmfHctDefMaxDuration_ID;
> > +  } else {
> > +    LOG_WA("Unknown attribute name %s", attr_name.c_str());
> > +    rc = NCSCC_RC_FAILURE;
> > +    goto done;
> > +  }
> > +
> > +  if (imm_attr->modType == SA_IMM_ATTR_VALUES_REPLACE) {
> > +    param.act = AVSV_OBJ_OPR_MOD;
> > +  } else if (imm_attr->modType == SA_IMM_ATTR_VALUES_DELETE) {
> > +    param.act = AVSV_OBJ_OPR_DEL;
> > +  } else {
> > +    LOG_WA("Unknown modificaton type %d", imm_attr->modType);
> > +    rc = NCSCC_RC_FAILURE;
> > +    goto done;
> > +  }
> > +
> > +  param.value_len = AvndImmUtil::value_size(imm_attr-
> > >modAttr.attrValueType);
> > +  memcpy(param.value, *imm_attr->modAttr.attrValues, param.value_len);
> > +
> > +  rc = avnd_hctype_oper_req(cb, &param);
> > +
> > +done:
> > +  return rc;
> > +}
> > +
> > +/**
> > + * IMM event handle, dispatch callback function for each changed attribute 
> > in
> > the current event.
> > + *
> > + * @param cb
> > + * @param evt
> > + *
> > + * @return NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE
> > + */
> > +uint32_t avnd_evt_imm_evh(AVND_CB *cb, AVND_EVT *evt) {
> > +  AVSV_AMF_CLASS_ID type;
> > +  uint32_t rc = NCSCC_RC_FAILURE;
> > +
> > +  TRACE_ENTER();
> > +
> > +  AvndImmEvt *imm_evt = (AvndImmEvt*) evt->info.imm.imm_evt;
> > +
> > +  // TODO(uabhano) change object_name_to_class_type argument to
> > std::string, then the SaNameT code below can be removed
> > +  SaNameT obj_name;
> > +  obj_name.length = imm_evt->get_object_name().size();
> > +  memcpy((char*)obj_name.value, imm_evt->get_object_name().c_str(),
> > obj_name.length);
> > +  type = AvndImmUtil::object_name_to_class_type(&obj_name);
> > +
> > +  for (std::vector<SaImmAttrModificationT_2*>::const_iterator it = imm_evt-
> > >begin(); it != imm_evt->end(); ++it) {
> > +    const SaImmAttrModificationT_2 *imm_attr = *it;
> > +    rc = AvndImm::update_callback_[type](imm_evt->get_object_name(),
> > imm_attr);
> > +  }
> > +
> > +  TRACE_LEAVE();
> > +  return rc;
> > +}
> > +
> > +/**
> > + * Handle imm apply, create and send an AvndImmEvt object to the avnd main
> > thread.
> > + *
> > + * @param immoi_handle
> > + * @param ccb_id
> > +  */
> > +void AvndImm::ccb_apply_cb(SaImmOiHandleT immoi_handle,
> > SaImmOiCcbIdT ccb_id) {
> > +  AVND_EVT_TYPE type = AVND_EVT_IMM;
> > +
> > +  AVND_EVT *evt = 0;
> > +  const SaImmAttrModificationT_2 *mod;
> > +  int i = 0;
> > +  CcbUtilCcbData_t *ccb_util_ccb_data;
> > +  CcbUtilOperationData_t *opdata = NULL;
> > +  AvndImmEvt *imm_evt;
> > +  uint32_t rc = NCSCC_RC_SUCCESS;
> > +  AVND_CB *cb = avnd_cb;
> > +
> > +  TRACE_ENTER2("CCB ID %llu", ccb_id);
> > +
> > +  while ((opdata = ccbutil_getNextCcbOp(ccb_id, opdata)) != NULL) {
> > +    imm_evt = new AvndImmEvt(opdata->objectName);
> > +    while ((mod = opdata->param.modify.attrMods[i++]) != NULL) {
> > +      imm_evt->set_mod_attr(*mod);
> > +    }
> > +
> > +    i = 0;
> > +
> > +    /* create and send an event */
> > +
> > +    evt = new AVND_EVT();
> > +
> > +    evt->type = type;
> > +    evt->priority = NCS_IPC_PRIORITY_NORMAL;
> > +    evt->info.imm.imm_evt = imm_evt;
> > +
> > +    rc = m_NCS_IPC_SEND(&cb->mbx, evt, evt->priority);
> > +    if (rc != NCSCC_RC_SUCCESS) {
> > +      LOG_CR("AvND send event to mailbox failed, type = %u", evt->type);
> > +    }
> > +  }
> > +
> > +  /* Return CCB container memory */
> > +  ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
> > +  osafassert(ccb_util_ccb_data);
> > +  ccbutil_deleteCcbData(ccb_util_ccb_data);
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +/**
> > + * IMM modify callback, memorize the request.
> > + *
> > + * @param immoi_handle
> > + * @param ccb_id
> > + * @param object_name
> > + * @param attr_mods
> > + *
> > + * @return SA_AIS_OK or or SA_AIS_ERR_xx
> > + */
> > +SaAisErrorT AvndImm::ccb_object_modify_cb(SaImmOiHandleT
> > immoi_handle,
> > +   SaImmOiCcbIdT ccb_id, const SaNameT *object_name,
> > +   const SaImmAttrModificationT_2 **attr_mods) {
> > +  SaAisErrorT rc = SA_AIS_OK;
> > +  struct CcbUtilCcbData *ccb_util_ccb_data;
> > +
> > +  TRACE_ENTER2("CCB ID %llu, %s", ccb_id, object_name->value);
> > +
> > +  if ((ccb_util_ccb_data = ccbutil_getCcbData(ccb_id)) != NULL) {
> > +    /* "memorize the request" */
> > +    if (ccbutil_ccbAddModifyOperation(ccb_util_ccb_data, object_name,
> > attr_mods) != 0) {
> > +      LOG_ER("Failed '%s'", object_name->value);
> > +      rc = SA_AIS_ERR_BAD_OPERATION;
> > +    }
> > +  } else {
> > +    LOG_ER("Failed to get CCB object for %llu", ccb_id);
> > +    rc = SA_AIS_ERR_NO_MEMORY;
> > +  }
> > +
> > +  TRACE_LEAVE();
> > +
> > +  return rc;
> > +}
> > +
> > +/**
> > + * IMM ccb abort callback.
> > + *
> > + * @param immoi_handle
> > + * @param ccb_id
> > + */
> > +void AvndImm::ccb_abort_cb(SaImmOiHandleT immoi_handle,
> > SaImmOiCcbIdT ccb_id) {
> > +  TRACE_ENTER();
> > +
> > +  CcbUtilCcbData_t *ccb_util_ccb_data;
> > +
> > +  /* Return CCB container memory */
> > +  ccb_util_ccb_data = ccbutil_findCcbData(ccb_id);
> > +  osafassert(ccb_util_ccb_data);
> > +  ccbutil_deleteCcbData(ccb_util_ccb_data);
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +/**
> > + * IMM ccb object delete callback.
> > + *
> > + * @param immoi_handle
> > + * @param ccb_id,
> > + * @param object_name
> > +  *
> > + * @return SA_AIS_OK
> > + */
> > +SaAisErrorT AvndImm::ccb_object_delete_cb(SaImmOiHandleT
> > immoi_handle,
> > +   SaImmOiCcbIdT ccb_id, const SaNameT *object_name) {
> > +
> > +  TRACE_ENTER();
> > +  TRACE_LEAVE();
> > +
> > +  return SA_AIS_OK;
> > +}
> > +
> > +/**
> > + * IMM ccb completed callback.
> > + *
> > + * @param immoi_handle
> > + * @param ccb_id,
> > +   *
> > + * @return SA_AIS_OK
> > + */
> > +SaAisErrorT AvndImm::ccb_completed_cb(SaImmOiHandleT immoi_handle,
> > +   SaImmOiCcbIdT ccb_id) {
> > +
> > +  TRACE_ENTER();
> > +  TRACE_LEAVE();
> > +
> > +  return SA_AIS_OK;
> > +}
> > +
> > +/**
> > + * IMM ccb object create callback.
> > + *
> > + * @param immoi_handle
> > + * @param ccb_id
> > + * @param class_name
> > + * @param parent_name
> > + * @param attr
> > + *
> > + * @return SA_AIS_OK
> > + */
> > +SaAisErrorT AvndImm::ccb_object_create_cb(SaImmOiHandleT
> > immoi_handle,
> > +   SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
> > +   const SaNameT *parent_name, const SaImmAttrValuesT_2 **attr) {
> > +
> > +  TRACE_ENTER();
> > +  TRACE_LEAVE();
> > +
> > +  return SA_AIS_OK;
> > +}
> > +
> > +const SaImmOiCallbacksT_2 AvndImm::avnd_callbacks_ = {
> > +  .saImmOiAdminOperationCallback = NULL,
> > +  .saImmOiCcbAbortCallback = ccb_abort_cb,
> > +  .saImmOiCcbApplyCallback = ccb_apply_cb,
> > +  .saImmOiCcbCompletedCallback = ccb_completed_cb,
> > +  .saImmOiCcbObjectCreateCallback = ccb_object_create_cb,
> > +  .saImmOiCcbObjectDeleteCallback = ccb_object_delete_cb,
> > +  .saImmOiCcbObjectModifyCallback = ccb_object_modify_cb,
> > +  .saImmOiRtAttrUpdateCallback = NULL
> > +};
> > +
> > +/**
> > + * Set IMM applier.
> > + *
> > + * @return SA_AIS_OK or or SA_AIS_ERR_xx
> > + */
> > +SaAisErrorT AvndImm::imm_applier_set() {
> > +  SaAisErrorT rc = SA_AIS_OK;
> > +  uint32_t i;
> > +  std::string applier_name = "@safAmfNodeDirector_";
> > +
> > +  TRACE_ENTER();
> > +
> > +  char hostname[_POSIX_HOST_NAME_MAX];
> > +  if (gethostname(hostname, _POSIX_HOST_NAME_MAX) == -1) {
> > +    LOG_ER("gethostname failed: %s\n", strerror(errno));
> > +
> > +    /* use the node id of the node on which the AVD is running instead. */
> > +    SaClmNodeIdT node_id_avnd = m_NCS_GET_NODE_ID;
> > +    snprintf(hostname, _POSIX_HOST_NAME_MAX, "%x", node_id_avnd);
> > +  }
> > +
> > +  applier_name += hostname;
> > +
> > +  LOG_NO("IMM applier name: %s", applier_name.c_str());
> > +
> > +  //
> > +  if ((rc = immutil_saImmOiImplementerSet(immOiHandle_, (char*)
> > applier_name.c_str())) != SA_AIS_OK) {
> > +    LOG_ER("saImmOiImplementerSet failed %u", rc);
> > +    return rc;
> > +  }
> > +
> > +  //
> > +  for (i = 0; i < AVND_SA_AMF_CLASS_MAX; i++) {
> > +    if ((rc = immutil_saImmOiClassImplementerSet(immOiHandle_,
> > avnd_class_names_[i])) != SA_AIS_OK) {
> > +      LOG_ER("Impl Set Failed for %s, returned %d", avnd_class_names_[i], 
> > rc);
> > +      break;
> > +    }
> > +  }
> > +
> > +  TRACE_LEAVE();
> > +
> > +  return rc;
> > +}
> > +
> > +/**
> > + * Initialize IMM.
> > + *
> > + * @return SA_AIS_OK or or SA_AIS_ERR_xx
> > + */
> > +SaAisErrorT AvndImm::imm_init() {
> > +  SaAisErrorT rc = SA_AIS_OK ;
> > +
> > +  TRACE_ENTER();
> > +
> > +  for (int i = 0; i < AVSV_SA_AMF_CLASS_MAX; ++i) {
> > +    update_callback_[i] = not_yet_implemented;
> > +  }
> > +
> > +  update_callback_[AVSV_SA_AMF_HEALTH_CHECK_TYPE] =
> > update_health_check_type;
> > +
> > +  /* Setup immutils profile once and for all */
> > +  immutilWrapperProfile.errorsAreFatal = false;
> > +  immutilWrapperProfile.retryInterval = 1000;
> > +  immutilWrapperProfile.nTries = 180;
> > +
> > +  if ((rc = immutil_saImmOiInitialize_2(&immOiHandle_, &avnd_callbacks_,
> > &immVersion_)) != SA_AIS_OK) {
> > +    LOG_ER("saImmOiInitialize failed %u", rc);
> > +    goto done;
> > +  }
> > +
> > +  if ((rc = immutil_saImmOmInitialize(&immOmHandle_, NULL,
> > &immVersion_)) != SA_AIS_OK) {
> > +    LOG_ER("saImmOmInitialize failed %u", rc);
> > +    goto done;
> > +  }
> > +
> > +  if ((rc = immutil_saImmOiSelectionObjectGet(immOiHandle_,
> > &imm_sel_obj_)) != SA_AIS_OK) {
> > +    LOG_ER("saImmOiSelectionObjectGet failed %u", rc);
> > +    goto done;
> > +  }
> > +
> > +  TRACE("Successfully initialized IMM");
> > +
> > +done:
> > +  TRACE_LEAVE();
> > +
> > +  return rc;
> > +}
> > +
> > +/**
> > + * IMM thread main function, waits for IMM events and dispatch callback
> > functions.
> > + */
> > +void AvndImm::imm_main() {
> > +  SaAisErrorT rc = SA_AIS_OK;
> > +
> > +  enum {
> > +    FD_IMM = 0
> > +  };
> > +
> > +  static nfds_t nfds = FD_IMM + 1;
> > +  int polltmo = -1;
> > +  static struct pollfd fds[FD_IMM + 1];
> > +
> > +  TRACE_ENTER();
> > +
> > +  fds[FD_IMM].fd = imm_sel_obj_;
> > +  fds[FD_IMM].events = POLLIN;
> > +  nfds = FD_IMM + 1;
> > +
> > +  while (true) {
> > +    int pollretval = poll(fds, nfds, polltmo);
> > +
> > +    if (pollretval == -1) {
> > +      if (errno == EINTR)
> > +        continue;
> > +
> > +      LOG_ER("main: poll FAILED - %s", strerror(errno));
> > +      break;
> > +    }
> > +
> > +    if (immOiHandle_ && fds[FD_IMM].revents & POLLIN) {
> > +      TRACE("IMM event rec");
> > +      rc = saImmOiDispatch(immOiHandle_, SA_DISPATCH_ALL);
> > +      if (rc != SA_AIS_OK) {
> > +        LOG_ER("saImmOiDispatch failed: %d", rc);
> > +
> > +      }
> > +    }
> > +  }
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +/**
> > + * IMM thread start function. Init IMM and set as applier.
> > + *
> > + * @return 0
> > + */
> > +void *AvndImm::imm_start(void *) {
> > +  SaAisErrorT rc = SA_AIS_OK;
> > +
> > +  TRACE_ENTER();
> > +
> > +  if ((rc = imm_init()) != SA_AIS_OK) {
> > +    LOG_ER("avnd_imm_init FAILED");
> > +    goto done;
> > +  }
> > +
> > +  if ((rc = imm_applier_set()) != SA_AIS_OK) {
> > +    LOG_ER("avnd_imm_applier set FAILED");
> > +    goto done;
> > +  }
> > +
> > +  imm_main();
> > +
> > +done:
> > +
> > +  return 0;
> > +}
> > +
> > +/**
> > + * Create IMM thread for applier functionality.
> > + *
> > + * @return NCSCC_RC_SUCCESS or NCSCC_RC_FAILURE
> > + */
> > +uint32_t avnd_create_imm_thread() {
> > +  uint32_t rc = NCSCC_RC_SUCCESS;
> > +  pthread_t thread;
> > +  pthread_attr_t attr;
> > +
> > +  TRACE_ENTER();
> > +
> > +  pthread_attr_init(&attr);
> > +  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
> > +
> > +  if (pthread_create(&thread, &attr, AvndImm::imm_start, 0) != 0) {
> > +    LOG_ER("pthread_create FAILED: %s", strerror(errno));
> > +    rc = NCSCC_RC_FAILURE;
> > +  }
> > +
> > +  pthread_attr_destroy(&attr);
> > +
> > +  TRACE_LEAVE();
> > +
> > +  return rc;
> > +}
> > +
> > diff --git a/osaf/services/saf/amf/amfnd/include/Makefile.am
> > b/osaf/services/saf/amf/amfnd/include/Makefile.am
> > --- a/osaf/services/saf/amf/amfnd/include/Makefile.am
> > +++ b/osaf/services/saf/amf/amfnd/include/Makefile.am
> > @@ -29,6 +29,7 @@ noinst_HEADERS = \
> >     avnd_evt.h \
> >     avnd.h \
> >     avnd_hc.h \
> > +   avnd_imm.h \
> >     avnd_mds.h \
> >     avnd_mon.h \
> >     avnd_pg.h \
> > diff --git a/osaf/services/saf/amf/amfnd/include/avnd.h
> > b/osaf/services/saf/amf/amfnd/include/avnd.h
> > --- a/osaf/services/saf/amf/amfnd/include/avnd.h
> > +++ b/osaf/services/saf/amf/amfnd/include/avnd.h
> > @@ -34,6 +34,7 @@
> >  #define AVND_H
> >
> >  #include <saImmOm.h>
> > +#include <saImmOi.h>
> >
> >  #include "amf.h"
> >  #include "ncs_main_papi.h"
> > diff --git a/osaf/services/saf/amf/amfnd/include/avnd_evt.h
> > b/osaf/services/saf/amf/amfnd/include/avnd_evt.h
> > --- a/osaf/services/saf/amf/amfnd/include/avnd_evt.h
> > +++ b/osaf/services/saf/amf/amfnd/include/avnd_evt.h
> > @@ -110,6 +110,8 @@ typedef enum avnd_evt_type {
> >     AVND_EVT_PID_EXIT,
> >     AVND_EVT_TMR_QSCING_CMPL,
> >
> > +   AVND_EVT_IMM,
> > +
> >     AVND_EVT_MAX
> >  } AVND_EVT_TYPE;
> >
> > @@ -155,6 +157,11 @@ typedef struct avnd_pm_mon_evt {
> >     AVND_COMP_PM_REC *pm_rec;
> >  } AVND_PM_MON_EVT;
> >
> > +/* imm event definition */
> > +typedef struct avnd_imm_evt {
> > +   void *imm_evt; /* AvndImmEvt ptr */
> > +} AVND_IMM_EVT;
> > +
> >  /* AVND top-level event structure */
> >  typedef struct avnd_evt_tag {
> >     struct avnd_evt_tag *next;
> > @@ -173,6 +180,7 @@ typedef struct avnd_evt_tag {
> >             AVND_CLC_EVT clc;
> >             AVND_COMP_FSM_EVT comp_fsm;
> >             AVND_PM_MON_EVT pm_evt;
> > +           AVND_IMM_EVT imm;
> >     } info;
> >
> >  } AVND_EVT;
> > diff --git a/osaf/services/saf/amf/amfnd/include/avnd_hc.h
> > b/osaf/services/saf/amf/amfnd/include/avnd_hc.h
> > --- a/osaf/services/saf/amf/amfnd/include/avnd_hc.h
> > +++ b/osaf/services/saf/amf/amfnd/include/avnd_hc.h
> > @@ -59,5 +59,6 @@ extern SaAisErrorT avnd_hc_config_get(st
> >  extern SaAisErrorT avnd_hctype_config_get(SaImmHandleT immOmHandle,
> > const SaNameT *comptype_dn);
> >  extern AVND_HCTYPE *avnd_hctypedb_rec_get(const SaNameT
> > *comp_type_dn, const SaAmfHealthcheckKeyT *key);
> >  extern uint32_t avnd_hc_oper_req(struct avnd_cb_tag *, AVSV_PARAM_INFO
> > *param);
> > +extern uint32_t avnd_hctype_oper_req(struct avnd_cb_tag *,
> > AVSV_PARAM_INFO *param);
> >
> >  #endif   /* !AVND_HC_H */
> > diff --git a/osaf/services/saf/amf/amfnd/include/avnd_imm.h
> > b/osaf/services/saf/amf/amfnd/include/avnd_imm.h
> > new file mode 100644
> > --- /dev/null
> > +++ b/osaf/services/saf/amf/amfnd/include/avnd_imm.h
> > @@ -0,0 +1,148 @@
> > +/*      -*- OpenSAF  -*-
> > + *
> > + * (C) Copyright 2014 The OpenSAF Foundation
> > + *
> > + * This program is distributed in the hope that it will be useful, but
> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
> > MERCHANTABILITY
> > + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
> > + * under the GNU Lesser General Public License Version 2.1, February 1999.
> > + * The complete license can be accessed from the following location:
> > + * http://opensource.org/licenses/lgpl-license.php
> > + * See the Copying file included with the OpenSAF distribution for full
> > + * licensing terms.
> > + *
> > + * Author(s): Ericsson AB
> > + *
> > + */
> > +
> > +/***********************************************************
> > ******************
> > +  DESCRIPTION:
> > +
> > +  Classes used for implementing AMF node director as an IMM applier.
> > +
> > +
> > *************************************************************
> > *****************
> > + */
> > +
> > +#ifndef AVND_IMM_H
> > +#define    AVND_IMM_H
> > +
> > +#ifdef __cplusplus
> > +
> > +#include <vector>
> > +#include <string>
> > +#include "avnd.h"
> > +
> > +//
> > +typedef enum {
> > +  AVND_SA_AMF_HEALTH_CHECK_TYPE = 0,
> > +  AVND_SA_AMF_CLASS_MAX
> > +} AVND_AMF_CLASS_ID;
> > +
> > +//--------------------------------------------------------------------------
> > +// < \ingroup avndImm
> > +//
> > +// This class is used as a container for one IMM modify callback.
> > +// >
> > +//--------------------------------------------------------------------------
> > +class AvndImmEvt {
> > +public:
> > +  //
> > +  explicit AvndImmEvt(const SaNameT& obj_name) : object_name_((const
> > char*) obj_name.value, obj_name.length) {}
> > +
> > +  //
> > +  ~AvndImmEvt();
> > +
> > +  //
> > +  std::string get_object_name() {return object_name_;}
> > +
> > +  //
> > +  void set_mod_attr(const SaImmAttrModificationT_2& attr);
> > +
> > +  //
> > +  typedef typename std::vector<SaImmAttrModificationT_2*>::const_iterator
> > const_iterator;
> > +  const_iterator begin() const {return attr_.begin();}
> > +  const_iterator end() const {return attr_.end();}
> > +
> > +private:
> > +  //
> > +  AvndImmEvt(const AvndImmEvt&);
> > +  void operator=(const AvndImmEvt&);
> > +
> > +  std::string object_name_;
> > +
> > +  std::vector<SaImmAttrModificationT_2*> attr_;
> > +};
> > +
> > +//--------------------------------------------------------------------------
> > +// < \ingroup avndImm
> > +//
> > +// This class contains utility functions for IMM.
> > +// >
> > +//--------------------------------------------------------------------------
> > +class AvndImmUtil {
> > +public:
> > +  //
> > +  static void deleteSaImmAttrValuesT(SaImmAttrValuesT_2& attr_value);
> > +  static void copySaImmAttrValuesT(SaImmAttrValuesT_2& to, const
> > SaImmAttrValuesT_2& from);
> > +  static char *str_dup(const char *str);
> > +  static size_t value_size(SaImmValueTypeT attrValueType);
> > +  static AVSV_AMF_CLASS_ID object_name_to_class_type(const SaNameT*
> > obj_name);
> > +  static void remove_attr(SaImmAttrModificationT_2* attr);
> > +private:
> > +  AvndImmUtil();
> > +  AvndImmUtil(const AvndImmUtil&);
> > +  void operator=(const AvndImmUtil&);
> > +};
> > +
> > +//--------------------------------------------------------------------------
> > +// < \ingroup avndImm
> > +//
> > +// This class contains IMM callback, init and set functions.
> > +// >
> > +//--------------------------------------------------------------------------
> > +class AvndImm {
> > + public:
> > +  //
> > +  typedef uint32_t (*UpdateFn) (const std::string& dn, const
> > SaImmAttrModificationT_2* attr);
> > +
> > +  //
> > +  static void ccb_abort_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT
> > ccb_id);
> > +  static SaAisErrorT ccb_object_delete_cb(SaImmOiHandleT immoi_handle,
> >     SaImmOiCcbIdT ccb_id, const SaNameT *object_name);
> > +  static void ccb_apply_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT
> > ccb_id);
> > +  static SaAisErrorT ccb_completed_cb(SaImmOiHandleT immoi_handle,
> > SaImmOiCcbIdT ccb_id);
> > +  static SaAisErrorT ccb_object_create_cb(SaImmOiHandleT immoi_handle,
> > SaImmOiCcbIdT ccb_id, const SaImmClassNameT class_name,
> > +                                          const SaNameT *parent_name, const
> > SaImmAttrValuesT_2 **attr);
> > +  static SaAisErrorT ccb_object_modify_cb(SaImmOiHandleT immoi_handle,
> > SaImmOiCcbIdT ccb_id, const SaNameT *object_name, const
> > SaImmAttrModificationT_2 **attr_mods);
> > +  static void *imm_start(void *);
> > +
> > +  //
> > +  static uint32_t not_yet_implemented(const std::string& object_name, const
> > SaImmAttrModificationT_2* imm_attr);
> > +  static uint32_t update_health_check_type(const std::string& object_name,
> > const SaImmAttrModificationT_2* imm_attr);
> > +
> > +  //
> > +  static SaVersionT immVersion_;
> > +  static SaImmOiHandleT immOiHandle_;
> > +  static SaImmOiHandleT immOmHandle_;
> > +  static SaSelectionObjectT imm_sel_obj_;
> > +  static UpdateFn update_callback_[AVSV_SA_AMF_CLASS_MAX];
> > +  static const char *avnd_class_names_[];
> > + private:
> > +  static SaAisErrorT imm_init();
> > +  static void imm_main();
> > +  static SaAisErrorT imm_applier_set();
> > +  static const SaImmOiCallbacksT_2 avnd_callbacks_;
> > +
> > +  //
> > +  AvndImm();
> > +  AvndImm(const AvndImmUtil&);
> > +  void operator=(const AvndImm&);
> > +};
> > +
> > +//
> > +extern uint32_t avnd_evt_imm_evh(AVND_CB *cb, AVND_EVT *evt);
> > +extern uint32_t avnd_create_imm_thread();
> > +
> > +#endif /* __cplusclpus */
> > +
> > +#endif     /* AVND_IMM_H */
> > +
> > diff --git a/osaf/services/saf/amf/amfnd/main.cc
> > b/osaf/services/saf/amf/amfnd/main.cc
> > --- a/osaf/services/saf/amf/amfnd/main.cc
> > +++ b/osaf/services/saf/amf/amfnd/main.cc
> > @@ -31,6 +31,7 @@
> >  #include "immutil.h"
> >  #include "logtrace.h"
> >  #include "nid_api.h"
> > +#include "avnd_imm.h"
> >
> >  #define FD_MBX   0
> >  #define FD_TERM  1
> > @@ -117,7 +118,8 @@ extern const AVND_EVT_HDLR g_avnd_func_l
> >     avnd_evt_comp_pres_fsm_evh,     /* AVND_EVT_COMP_PRES_FSM_EV
> > */
> >     avnd_evt_last_step_term_evh,    /* AVND_EVT_LAST_STEP_TERM */
> >     avnd_evt_pid_exit_evh,  /* AVND_EVT_PID_EXIT */
> > -   avnd_evt_tmr_qscing_cmpl_evh    /*
> > AVND_EVT_TMR_QSCING_CMPL */
> > +   avnd_evt_tmr_qscing_cmpl_evh,   /*
> > AVND_EVT_TMR_QSCING_CMPL */
> > +   avnd_evt_imm_evh                /* AVND_EVT_IMML */
> >  };
> >
> >  /* global task handle */
> > @@ -273,6 +275,12 @@ uint32_t avnd_create(void)
> >             rc = NCSCC_RC_FAILURE;
> >             goto done;
> >     }
> > +
> > +   rc = avnd_create_imm_thread();
> > +   if (NCSCC_RC_SUCCESS != rc) {
> > +           rc = NCSCC_RC_FAILURE;
> > +           goto done;
> > +   }
> >
> >  done:
> >     TRACE_LEAVE();

------------------------------------------------------------------------------
Time is money. Stop wasting it! Get your web API in 5 minutes.
www.restlet.com/download
http://p.sf.net/sfu/restlet
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to