Ack with comments.

1. Please change name of init_clc_cli_commands to 
init_clc_cli_commands_and_timeouts. 
2. If I am configuring saAmfCtRelPathInstantiateCmd with relative patch 
(/opt/amf_demo) and also configure saAmfCtSwBundle, then it is only taking 
saAmfCtRelPathInstantiateCmd. This need to be documented.

Thanks
-Nagu

> -----Original Message-----
> From: Hans Feldt [mailto:osafde...@gmail.com]
> Sent: 28 January 2014 19:11
> To: Nagendra Kumar
> Cc: opensaf-devel@lists.sourceforge.net
> Subject: [PATCH 2 of 2] amfnd: ignore saAmfCtSwBundle when abspath in CLC-
> CLI cmds [#662]
> 
>  osaf/services/saf/amf/amfnd/compdb.cc |  290 ++++++++++++--------------------
> -
>  1 files changed, 108 insertions(+), 182 deletions(-)
> 
> 
> diff --git a/osaf/services/saf/amf/amfnd/compdb.cc
> b/osaf/services/saf/amf/amfnd/compdb.cc
> --- a/osaf/services/saf/amf/amfnd/compdb.cc
> +++ b/osaf/services/saf/amf/amfnd/compdb.cc
> @@ -956,10 +956,10 @@ static amf_comp_type_t *avnd_comptype_cr
>       if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCtCompCategory"),
> attributes, 0, &compt->saAmfCtCompCategory) != SA_AIS_OK)
>               osafassert(0);
> 
> -     if (IS_COMP_LOCAL(compt->saAmfCtCompCategory) &&
> -
> immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCtSwBundle"),
> attributes, 0, &compt->saAmfCtSwBundle) != SA_AIS_OK) {
> -             osafassert(0);
> -             return NULL;
> +     if (IS_COMP_LOCAL(compt->saAmfCtCompCategory)) {
> +             // Ignore if bundle not found, commands can be absolute path
> +
>       immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCtSwBundle"),
> +                     attributes, 0, &compt->saAmfCtSwBundle);
>       }
> 
> 
> immutil_getAttrValuesNumber(const_cast<SaImmAttrNameT>("saAmfCtDefCm
> dEnv"), attributes, &j);
> @@ -1170,170 +1170,145 @@ done:
>  }
> 
>  /**
> - * Initialize the bundle dependent attributes in comp (the
> - * CLC-CLI commands).
> - *
> - * If path in comptype for AM & HC scripts is absolute it is
> - * used, else (it is relative) it is prepended with path prefix.
> + * Initializes a single CLC-CLI command for a component.
> + *
> + * If path in comptype is absolute it is used, else (it is relative) it is
> + * prepended with path prefix.
> + *
> + * @param cmd
> + * @param clc_cmd
> + * @param type_cmd_argv
> + * @param path_prefix
> + * @param attributes
> + * @param attr_name
> + */
> +static void init_clc_cli_command(AVND_COMP_CLC_CMD_PARAM *cmd,
> const char *clc_cmd,
> +             char **clc_cmd_argv, const char *path_prefix,
> +             const SaImmAttrValuesT_2 **attributes,
> +             const char *attr_name)
> +{
> +     char *buf = cmd->cmd;
> +     int i, j;
> +     const char *argv;
> +
> +     // prepend with path prefix (from saAmfNodeSwBundlePathPrefix) if
> needed
> +     if (clc_cmd[0] == '/')
> +             i = snprintf(buf, sizeof(cmd->cmd), "%s", clc_cmd);
> +     else
> +             i = snprintf(buf, sizeof(cmd->cmd), "%s/%s",    path_prefix,
> clc_cmd);
> +
> +     // append argv from comp type
> +     j = 0;
> +     while ((argv = clc_cmd_argv[j++]) != NULL)
> +             i += snprintf(&buf[i], sizeof(cmd->cmd) - i, " %s", argv);
> +
> +     // append argv from comp instance
> +     j = 0;
> +     while ((argv = immutil_getStringAttr(attributes, attr_name, j++)) !=
> NULL)
> +             i += snprintf(&buf[i], sizeof(cmd->cmd) - i, " %s", argv);
> +
> +     cmd->len = i;
> +
> +     /* Check for truncation, should alloc these strings dynamically instead
> */
> +     osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd)));
> +     TRACE("cmd=%s", cmd->cmd);
> +}
> +
> +/**
> + * Initializes the CLC-CLI commands for a component.
>   *
>   * @param comp
>   * @param comptype
>   * @param path_prefix
>   * @param attributes
>   */
> -static void init_bundle_dependent_attributes(AVND_COMP *comp,
> +static void init_clc_cli_commands(AVND_COMP *comp,
>                               const amf_comp_type_t *comptype,
>                               const char *path_prefix,
>                               const SaImmAttrValuesT_2 **attributes)
>  {
> -     int i, j;
>       AVND_COMP_CLC_CMD_PARAM *cmd;
> -     const char *argv;
> +
>       TRACE_ENTER();
> 
>       cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_INSTANTIATE - 1];
>       if (comptype->saAmfCtRelPathInstantiateCmd != NULL) {
> -             i = 0;
> -             i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s/%s",
> -                     path_prefix, comptype-
> >saAmfCtRelPathInstantiateCmd);
> +             init_clc_cli_command(cmd, comptype-
> >saAmfCtRelPathInstantiateCmd,
> +                             comptype->saAmfCtDefInstantiateCmdArgv,
> path_prefix,
> +                             attributes, "saAmfCompInstantiateCmdArgv");
> +     }
> 
> -             j = 0;
> -             while ((argv = comptype-
> >saAmfCtDefInstantiateCmdArgv[j++]) != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             j = 0;
> -             while ((argv = immutil_getStringAttr(attributes,
> "saAmfCompInstantiateCmdArgv", j++)) != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             cmd->len = i;
> -
> -             /* Check for truncation, should alloc these strings dynamically
> instead */
> -             osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd)));
> -             TRACE("cmd=%s", cmd->cmd);
> +     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompInstantiateTimeo
> ut"),
> +                     attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> +             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
> +             comp->pxied_inst_cbk_timeout = comptype-
> >saAmfCtDefCallbackTimeout;
> +     } else {
> +             comp->pxied_inst_cbk_timeout = cmd->timeout;
>       }
> 
>       cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_TERMINATE - 1];
>       if (comptype->saAmfCtRelPathTerminateCmd != NULL) {
> -             i = 0;
> -             i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s/%s",
> -                     path_prefix, comptype-
> >saAmfCtRelPathTerminateCmd);
> +             init_clc_cli_command(cmd, comptype-
> >saAmfCtRelPathTerminateCmd,
> +                             comptype->saAmfCtDefTerminateCmdArgv,
> path_prefix,
> +                             attributes, "saAmfCompTerminateCmdArgv");
> +     }
> 
> -             j = 0;
> -             while ((argv = comptype->saAmfCtDefTerminateCmdArgv[j++])
> != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             j = 0;
> -             while ((argv = immutil_getStringAttr(attributes,
> "saAmfCompTerminateCmdArgv", j++)) != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             cmd->len = i;
> -
> -             /* Check for truncation, should alloc these strings dynamically
> instead */
> -             osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd)));
> -             TRACE("cmd=%s", cmd->cmd);
> +     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompTerminateTimeo
> ut"),
> +                     attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> +             if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp)) {
> +                     cmd->timeout = comptype-
> >saAmfCtDefCallbackTimeout;
> +                     comp->term_cbk_timeout = cmd->timeout;
> +             }
> +             else
> +                     cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
>       }
> 
>       cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_CLEANUP - 1];
>       if (comptype->saAmfCtRelPathCleanupCmd != NULL) {
> -             i = 0;
> -             i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s/%s",
> -                     path_prefix, comptype->saAmfCtRelPathCleanupCmd);
> +             init_clc_cli_command(cmd, comptype-
> >saAmfCtRelPathCleanupCmd,
> +                             comptype->saAmfCtDefCleanupCmdArgv,
> path_prefix,
> +                             attributes, "saAmfCompCleanupCmdArgv");
> +     }
> 
> -             j = 0;
> -             while ((argv = comptype->saAmfCtDefCleanupCmdArgv[j++])
> != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             j = 0;
> -             while ((argv = immutil_getStringAttr(attributes,
> "saAmfCompCleanupCmdArgv", j++)) != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             cmd->len = i;
> -
> -             /* Check for truncation, should alloc these strings dynamically
> instead */
> -             osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd)));
> -             TRACE("cmd=%s", cmd->cmd);
> +     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompCleanupTimeout"
> ),
> +                     attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> +             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
> +             comp->pxied_clean_cbk_timeout = comptype-
> >saAmfCtDefCallbackTimeout;
> +     } else {
> +             comp->pxied_clean_cbk_timeout = cmd->timeout;
>       }
> 
>       cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTART - 1];
>       if (comptype->saAmfCtRelPathAmStartCmd != NULL) {
> -             i = 0;
> +             init_clc_cli_command(cmd, comptype-
> >saAmfCtRelPathAmStartCmd,
> +                             comptype->saAmfCtDefAmStartCmdArgv,
> path_prefix,
> +                             attributes, "saAmfCompAmStartCmdArgv");
> +             comp->is_am_en = true;
> +     }
> 
> -             if (comptype->saAmfCtRelPathAmStartCmd[0] == '/')
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
> "%s",
> -                             comptype->saAmfCtRelPathAmStartCmd);
> -             else
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
> "%s/%s",
> -                             path_prefix, comptype-
> >saAmfCtRelPathAmStartCmd);
> -
> -             j = 0;
> -             while ((argv = comptype->saAmfCtDefAmStartCmdArgv[j++])
> != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             j = 0;
> -             while ((argv = immutil_getStringAttr(attributes,
> "saAmfCompAmStartCmdArgv", j++)) != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             cmd->len = i;
> -
> -             comp->is_am_en = true;
> -
> -             /* Check for truncation, should alloc these strings dynamically
> instead */
> -             osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd)));
> -             TRACE("cmd=%s", cmd->cmd);
> +     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStartTimeout
> "),
> +                     attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> +             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
>       }
> 
>       cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTOP - 1];
>       if (comptype->saAmfCtRelPathAmStopCmd != NULL) {
> -             i = 0;
> +             init_clc_cli_command(cmd, comptype-
> >saAmfCtRelPathAmStopCmd,
> +                             comptype->saAmfCtDefAmStopCmdArgv,
> path_prefix,
> +                             attributes, "saAmfCompAmStopCmdArgv");
> +     }
> 
> -             if (comptype->saAmfCtRelPathAmStopCmd[0] == '/')
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
> "%s",
> -                             comptype->saAmfCtRelPathAmStopCmd);
> -             else
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
> "%s/%s",
> -                             path_prefix, comptype-
> >saAmfCtRelPathAmStopCmd);
> -
> -             j = 0;
> -             while ((argv = comptype->saAmfCtDefAmStopCmdArgv[j++])
> != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             j = 0;
> -             while ((argv = immutil_getStringAttr(attributes,
> "saAmfCompAmStopCmdArgv", j++)) != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             cmd->len = i;
> -
> -             /* Check for truncation, should alloc these strings dynamically
> instead */
> -             osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd)));
> -             TRACE("cmd=%s", cmd->cmd);
> +     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStopTimeout"
> ),
> +                     attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> +             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
>       }
> 
>       cmd = &comp->clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_HC - 1];
>       if (comptype->osafAmfCtRelPathHcCmd != NULL) {
> -             i = 0;
> -
> -             if (comptype->osafAmfCtRelPathHcCmd[0] == '/')
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
> "%s",
> -                             comptype->osafAmfCtRelPathHcCmd);
> -             else
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
> "%s/%s",
> -                             path_prefix, comptype-
> >osafAmfCtRelPathHcCmd);
> -
> -             j = 0;
> -             while ((argv = comptype->osafAmfCtDefHcCmdArgv[j++]) !=
> NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             j = 0;
> -             while ((argv = immutil_getStringAttr(attributes,
> "osafAmfCompHcCmdArgv", j++)) != NULL)
> -                     i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
> %s", argv);
> -
> -             cmd->len = i;
> -
> +             init_clc_cli_command(cmd, comptype-
> >osafAmfCtRelPathHcCmd,
> +                             comptype->osafAmfCtDefHcCmdArgv,
> path_prefix,
> +                             attributes, "osafAmfCompHcCmdArgv");
>               comp->is_hc_cmd_configured = true;
> -
> -             /* Check for truncation, should alloc these strings dynamically
> instead */
> -             osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd)));
> -             TRACE("cmd=%s", cmd->cmd);
>       }
> 
>       TRACE_LEAVE();
> @@ -1344,16 +1319,12 @@ static void init_bundle_dependent_attrib
>   *
>   * @param comp
>   * @param attributes
> - * @param bundle_missing_is_error if true skip further initialization and 
> return
> error code.
> - * if false continue initialization to get most attributes correct.
>   *
>   * @return int
>   */
> -static int comp_init(AVND_COMP *comp, const SaImmAttrValuesT_2
> **attributes,
> -     bool bundle_missing_is_error)
> +static int comp_init(AVND_COMP *comp, const SaImmAttrValuesT_2
> **attributes)
>  {
>       int res = -1;
> -     AVND_COMP_CLC_CMD_PARAM *cmd;
>       amf_comp_type_t *comptype;
>       SaNameT nodeswbundle_name;
>       SaBoolT disable_restart;
> @@ -1380,30 +1351,11 @@ static int comp_init(AVND_COMP *comp, co
>       avsv_create_association_class_dn(&comptype->saAmfCtSwBundle,
>               &avnd_cb->amf_nodeName, "safInstalledSwBundle",
> &nodeswbundle_name);
> 
> -     res = get_string_attr_from_imm(immOmHandle,
> const_cast<SaImmAttrNameT>("saAmfNodeSwBundlePathPrefix"),
> +     (void) get_string_attr_from_imm(immOmHandle,
> +
>       const_cast<SaImmAttrNameT>("saAmfNodeSwBundlePathPrefix"),
>               &nodeswbundle_name, &path_prefix);
> 
> -     if (res == 0) {
> -             init_bundle_dependent_attributes(comp, comptype,
> path_prefix, attributes);
> -     } else {
> -             if (bundle_missing_is_error) {
> -                     LOG_NO("%s: '%s'", __FUNCTION__, comp-
> >name.value);
> -                     LOG_ER("%s: FAILED to read '%s'", __FUNCTION__,
> nodeswbundle_name.value);
> -                     goto done;
> -             } else {
> -                     TRACE("%s is missing, will refresh attributes later",
> nodeswbundle_name.value);
> -                     /* Continue initialization to get the correct type set.
> Especially
> -                      * pre-instantiable or not is important when instantion
> request comes. */
> -             }
> -     }
> -
> -     cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_INSTANTIATE - 1];
> -     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompInstantiateTimeo
> ut"), attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> -             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
> -             comp->pxied_inst_cbk_timeout = comptype-
> >saAmfCtDefCallbackTimeout;
> -     } else {
> -             comp->pxied_inst_cbk_timeout = cmd->timeout;
> -     }
> +     init_clc_cli_commands(comp, comptype, path_prefix, attributes);
> 
>       if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompInstantiationLeve
> l"), attributes, 0, &comp->inst_level) != SA_AIS_OK)
>               comp->inst_level = comptype->saAmfCtDefInstantiationLevel;
> @@ -1423,26 +1375,10 @@ static int comp_init(AVND_COMP *comp, co
>               comp->inst_retry_delay =
> comp_global_attrs.saAmfDelayBetweenInstantiateAttempts;
>  #endif
> 
> -     cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_CLEANUP - 1];
> -     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompCleanupTimeout"
> ), attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> -             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
> -             comp->pxied_clean_cbk_timeout = comptype-
> >saAmfCtDefCallbackTimeout;
> -     } else {
> -             comp->pxied_clean_cbk_timeout = cmd->timeout;
> -     }
> -
> -     cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTART - 1];
> -     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStartTimeout
> "), attributes, 0, &cmd->timeout) != SA_AIS_OK)
> -             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
> -
>       if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompNumMaxAmStart
> Attempts"), attributes,
>                           0, &comp->clc_info.am_start_retry_max) !=
> SA_AIS_OK)
>               comp->clc_info.am_start_retry_max =
> comp_global_attrs.saAmfNumMaxAmStartAttempts;
> 
> -     cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTOP - 1];
> -     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStopTimeout"
> ), attributes, 0, &cmd->timeout) != SA_AIS_OK)
> -             cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
> -
>       if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompNumMaxAmStop
> Attempts"), attributes,
>                           0, &comp-
> >clc_info.saAmfCompNumMaxAmStopAttempts) != SA_AIS_OK)
>               comp->clc_info.saAmfCompNumMaxAmStopAttempts =
> comp_global_attrs.saAmfNumMaxAmStopAttempts;
> @@ -1476,16 +1412,6 @@ static int comp_init(AVND_COMP *comp, co
> 
>       init_comp_category(comp, comptype->saAmfCtCompCategory);
> 
> -     cmd = &comp-
> >clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_TERMINATE - 1];
> -     if
> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompTerminateTimeo
> ut"), attributes, 0, &cmd->timeout) != SA_AIS_OK) {
> -             if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp)) {
> -                     cmd->timeout = comptype-
> >saAmfCtDefCallbackTimeout;
> -                     comp->term_cbk_timeout = cmd->timeout;
> -             }
> -             else
> -                     cmd->timeout = comptype->saAmfCtDefClcCliTimeout;
> -     }
> -
>       if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp))
>               m_AVND_COMP_OPER_STATE_SET(comp,
> SA_AMF_OPERATIONAL_DISABLED);
>       else
> @@ -1598,7 +1524,7 @@ static AVND_COMP *avnd_comp_create(const
>       error =
> immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompType"), attributes,
> 0, &comp->saAmfCompType);
>       osafassert(error == SA_AIS_OK);
> 
> -     if (comp_init(comp, attributes, false) != 0)
> +     if (comp_init(comp, attributes) != 0)
>               goto done;
> 
>       /* create the association with hdl-mngr */
> @@ -1776,7 +1702,7 @@ int avnd_comp_config_reinit(AVND_COMP *c
>               goto done2;
>       }
> 
> -     res = comp_init(comp, attributes, true);
> +     res = comp_init(comp, attributes);
>       if (res == 0)
>               TRACE("'%s' configuration reread from IMM", comp-
> >name.value);
> 

------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to