About comment nr1, I am not sure what I am talking about yet...
/HansF

> -----Original Message-----
> From: Hans Feldt [mailto:[email protected]]
> Sent: den 26 maj 2014 15:34
> To: Hans Nordebäck; [email protected]; [email protected]
> Cc: [email protected]
> Subject: Re: [devel] [PATCH 1 of 1] AMF: Use IMM applier in the AMF node 
> director V2 [#819]
> 
> Some comments:
> - I think a CCB Container should be a general independent class. Now it is 
> part of class AvndImmEvt. Seems like it could be used
> directly from the modify callback.
> - If e.g. a HC type is changed it could is perfectly normal/OK that it does 
> not exist on a specific node. This means this case should not
> log any error.
> - please add a doxygen header to each function/method describing its purpose, 
> descriptive comments as google style requires
> - imm.cc is perhaps not such a great name, what is the logical function here? 
> Perhaps amf_applier.cc or something similar?
> - comment "remove trace" means ENTER AND LEAVE
> - for logs add "context" for example function name: log("%s: bla", 
> __FUNCTION__);
> 
> See inline
> Thanks,
> Hans
> 
> > -----Original Message-----
> > From: Hans Nordebäck
> > Sent: den 22 maj 2014 15:05
> > To: Hans Feldt; [email protected]; [email protected]
> > Cc: [email protected]
> > Subject: [PATCH 1 of 1] AMF: Use IMM applier in the AMF node director V2 
> > [#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             |  159 ++++
> >  osaf/services/saf/amf/amfnd/imm.cc              |  765 
> > ++++++++++++++++++++++++
> >  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  |  136 ++++
> >  osaf/services/saf/amf/amfnd/main.cc             |   10 +-
> >  11 files changed, 1094 insertions(+), 1 deletions(-)
> >
> >
> > This first patch adds support for changing attributes in class 
> > SaAmfHealthcheckType
> >
> > 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,
> > +} AVSV_AMF_HEALTHCHECK_TYPE_ATTR_ID;
> [Hans] remove AVSV prefix, no longer exist
> 
> >
> >  #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"
> [Hans] remove avnd_ prefix, include using "include/xxx" according to google 
> rules
> 
> >
> >  
> > /****************************************************************************
> >    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,102 @@ SaAisErrorT avnd_hctype_config_get(SaImm
> >     return error;
> >  }
> >
> > +//
> > +std::string get_healtcheck_key(const std::string& dn)
> [Hans] I don't understand what this function does, it is probably general so 
> either 1) something similar already exist or it should be
> added to common general utilities.
> 
> > +{
> > +   std::string err_str;
> > +
> > +   std::string::size_type idx = dn.find("=");
> > +
> > +   // found?
> > +   if(idx == std::string::npos)
> > +   {
> > +           return err_str;
> > +   }
> > +
> > +   std::string part1 = dn.substr(0, idx);
> > +   if (part1 != "safHealthcheckKey")
> > +   {
> > +           return err_str;
> > +   }
> > +
> > +   std::string part2 = dn.substr(idx + 1);
> > +
> > +   idx = part2.find(",");
> > +
> > +   if(idx == std::string::npos)
> > +   {
> > +           return err_str;
> > +   }
> > +
> > +   std::string value = part2.substr(0, idx);
> > +
> > +   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 = get_healtcheck_key((const 
> > char*)param->name.value);
> > +                   if (hlt_chk_key.size() == 0)
> > +                   {
> > +                           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);
> [Hans] log or trace here?
> > +                                           break;
> > +                                   case saAmfHctDefMaxDuration_ID:
> > +                                           comp_hc_rec->max_dur = 
> > *((SaTimeT *)param->value);
> [Hans] log or trace here?
> > +                                           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 +498,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;
> > +           }
> [Hans] not exist is normal, move check up
> 
> > +
> > +           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 {
> [Hans] not exist is normal, move check up
> 
> > +                   /*
> > +                   ** 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,765 @@
> > +/*      -*- 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
> > +static const char *avnd_class_names[] = {
> > +  "SaAmfHealthcheckType"
> > +};
> > +
> > +/**
> > + * This method adds imm modification attribute to attribute vector
> > + * @param imm mod attribute
> > + *
> > + * @return none
> > + */
> > +void AvndImmEvt::set_mod_attr(const SaImmAttrModificationT_2& attr) {
> > +  TRACE_ENTER();
> [Hans] remove trace
> 
> > +
> > +  SaImmAttrModificationT_2 *tmp = new SaImmAttrModificationT_2;
> > +  tmp->modType = attr.modType;
> > +  AvndImmUtil::copySaImmAttrValuesT(tmp->modAttr, attr.modAttr);
> > +  attr_.push_back(tmp);
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +
> > +/**
> > + * Destructor
> > + *
> > + * @return none
> > + */
> > +AvndImmEvt::~AvndImmEvt() {
> > +  TRACE_ENTER();
> [Hans] remove trace
> 
> > +
> > +  std::for_each(attr_.begin(), attr_.end(), AvndImmUtil::remove_attr);
> > +  attr_.clear();
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +/**
> > + * This method adds imm modification attribute to attribute vector
> [Hans] ?
> 
> > + * @param imm mod attribute
> > + *
> > + * @return none
> > + */
> > +char *AvndImmUtil::str_dup(const char *s) {
> > +  char *c = new char[strlen(s) + 1];
> > +  std::strcpy(c, s);
> > +  return c;
> > +}
> > +
> > +/**
> > + * Utility methon returns size of given attribute value type.
> > + * @param attrValueType
> > + *
> > + * @return attrValueType size
> > + */
> > +size_t AvndImmUtil::value_size(SaImmValueTypeT attrValueType) {
> [Hans] should be an immutil function
> 
> > +  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 cb
> > + * @param evt
> > + *
> > + * @return SaAisErrorT
> > + */
> > +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;
> 
> [Hans] why is this needed? Amf nd will only ever handle a small subset of all 
> classes, besides something similar already exist in amfd,
> reuse?
> 
> > +
> > +  /* 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 pointer to attrValueType
> > + *
> > + * @return none
> > + */
> > +void AvndImmUtil::remove_attr(SaImmAttrModificationT_2* attr) {
> > +  TRACE_ENTER();
> [Hans] remove trace
> 
> > +
> > +  AvndImmUtil::deleteSaImmAttrValuesT(attr->modAttr);
> > +  delete attr;
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +/**
> > + * Delete attribute values.
> > + * @param reference to attrValue
> > + *
> > + * @return none
> > + */
> > +void AvndImmUtil::deleteSaImmAttrValuesT(SaImmAttrValuesT_2& attr_value) {
> > +  unsigned int i;
> > +
> > +  TRACE_ENTER();
> [Hans] remove trace
> > +
> > +  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;
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +/**
> > + * Copy imm attr values,
> > + * @param to
> > + * @param from
> > + *
> > + * @return none
> > + */
> > +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;
> > +
> > +  TRACE_ENTER();
> [Hans] remove trace
> 
> > +
> > +  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;
> > +  }
> > +
> > +  TRACE_LEAVE();
> > +}
> > +
> > +/**
> > + * 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 update health check type.
> > + * @param object_name
> > + * @param imm_attr
> > + *
> > + * @return   NCSCC_RC_SUCCESS/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 SaAisErrorT
> > + */
> > +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
> > + *
> > + * @return SaAisErrorT
> > + */
> > +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 object_name
> > + * @param attr_mods
> > + *
> > + * @return SaAisErrorT
> > + */
> > +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;
> 
> [Hans] ccb_util_ccb_data needs to be stored somewhere between invocations
> 
> > +
> > +  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 object_name
> > + * @param ccb_id
> > + *
> > + * @return none
> > + */
> > +void AvndImm::ccb_abort_cb(SaImmOiHandleT immoi_handle, SaImmOiCcbIdT 
> > ccb_id) {
> > +  TRACE_ENTER();
> [Hans] abort needs to free the CCB container, otherwise mem leak!
> 
> > +  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
> > + * @paramparent_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.
> > + * @param none
> > + *
> > + * @return SaAisErrorT
> > + */
> > +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;
> > +}
> > +
> > +/**
> > + * Init imm.
> > + * @param none
> > + *
> > + * @return SaAisErrorT
> > + */
> > +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.
> > + * @param none
> > + *
> > + * @return none
> > + */
> > +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.
> > + * @param none
> > + *
> > + * @return none
> > + */
> > +void *AvndImm::imm_start(void *) {
> > +  SaAisErrorT rc = SA_AIS_OK;
> > +
> > +  TRACE_ENTER();
> > +
> > +  if ((rc = imm_init()) != SA_AIS_OK) {
> [Hans] error handling?
> 
> > +  }
> > +
> > +  if ((rc = imm_applier_set()) != SA_AIS_OK) {
> [Hans] error handling?
> 
> > +  }
> > +
> > +  imm_main();
> > +
> > +  return 0;
> > +}
> > +
> > +/**
> > + * Create imm thread for applier functionality.
> > + * @param none
> > + *
> > + * @return NCSCC_RC_SUCCESS/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,136 @@
> > +/*      -*- 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:
> > +
> > +  AvND Error related definitions.
> 
> [Hans] ?
> 
> > +
> > + 
> > ******************************************************************************
> > + */
> > +
> > +#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;
> > +
> > +//
> > +class AvndImmEvt {
> > +public:
> > +  //
> > +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_;
> > +};
> > +
> > +//
> > +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&);
> > +};
> > +
> > +//
> > +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];
> > +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();
> 
> ------------------------------------------------------------------------------
> The best possible search technologies are now affordable for all companies.
> Download your FREE open source Enterprise Search Engine today!
> Our experts will assist you in its installation for $59/mo, no commitment.
> Test it for FREE on our Cloud platform anytime!
> http://pubads.g.doubleclick.net/gampad/clk?id=145328191&iu=/4140/ostg.clktrk
> _______________________________________________
> Opensaf-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/opensaf-devel

------------------------------------------------------------------------------
The best possible search technologies are now affordable for all companies.
Download your FREE open source Enterprise Search Engine today!
Our experts will assist you in its installation for $59/mo, no commitment.
Test it for FREE on our Cloud platform anytime!
http://pubads.g.doubleclick.net/gampad/clk?id=145328191&iu=/4140/ostg.clktrk
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to