Object modify is added
ccbdemo_modify updated with demo code for object modify
Also some cleanup and bug fixes
---
.../smfd/imm_modify_config/add_operation_to_ccb.cc | 105 ++++++-
.../smfd/imm_modify_config/add_operation_to_ccb.h | 13 +-
src/smf/smfd/imm_modify_config/attribute.cc | 320 ++++++++++++++++++---
src/smf/smfd/imm_modify_config/attribute.h | 79 +++--
src/smf/smfd/imm_modify_config/immccb.cc | 265 ++++++++---------
src/smf/smfd/imm_modify_config/immccb.h | 26 +-
src/smf/smfd/imm_modify_demo/ccbdemo_create.cc | 4 +-
src/smf/smfd/imm_modify_demo/ccbdemo_delete.cc | 4 +-
src/smf/smfd/imm_modify_demo/ccbdemo_modify.cc | 119 ++++++--
src/smf/smfd/imm_om_api/common/imm_attribute.h | 3 -
src/smf/smfd/imm_om_api/om_ccb_object_create.h | 3 -
11 files changed, 669 insertions(+), 272 deletions(-)
diff --git a/src/smf/smfd/imm_modify_config/add_operation_to_ccb.cc
b/src/smf/smfd/imm_modify_config/add_operation_to_ccb.cc
index 9db1ab1c5..6948aa89c 100644
--- a/src/smf/smfd/imm_modify_config/add_operation_to_ccb.cc
+++ b/src/smf/smfd/imm_modify_config/add_operation_to_ccb.cc
@@ -49,7 +49,7 @@ bool IsResorceAbort(const SaImmCcbHandleT& ccbHandle) {
const SaStringT *errString = nullptr;
SaAisErrorT ais_rc = saImmOmCcbGetErrorStrings(ccbHandle, &errString);
if ((ais_rc == SA_AIS_OK) && (errString != nullptr)) {
- TRACE("%s: Error string: '%s'", __FUNCTION__, errString[0]);
+ TRACE("LLDTEST %s: Error string: '%s'", __FUNCTION__, errString[0]);
std::string err_str(errString[0]);
if (err_str.find("IMM: Resource abort: ") != std::string::npos) {
// Is Resource Abort
@@ -60,7 +60,7 @@ bool IsResorceAbort(const SaImmCcbHandleT& ccbHandle) {
return rc;
}
-int AddObjectCreateToCcb(const SaImmCcbHandleT& ccb_handle,
+int AddCreateToCcb(const SaImmCcbHandleT& ccb_handle,
const modelmodify::CreateDescriptor& create_descriptor)
{
TRACE_ENTER2("LLDTEST1: Parent '%s', Class '%s'",
create_descriptor.parent_name.c_str(),
@@ -84,7 +84,7 @@ int AddObjectCreateToCcb(const SaImmCcbHandleT& ccb_handle,
// attribute values. This vector must have the same scope as the
// creator.
modelmodify::AttributeHandler attributes(&creator);
- if(attributes.AddAttributes(create_descriptor) == false) {
+ if(attributes.AddAttributesForObjectCreate(create_descriptor) == false) {
LOG_NO("LLDTEST1 %s: SetAttributeValues() Fail", __FUNCTION__);
recovery_info = modelmodify::kFail;
}
@@ -125,16 +125,10 @@ int AddObjectCreateToCcb(const SaImmCcbHandleT&
ccb_handle,
return recovery_info;
}
-// Add one delete operation to a CCB
-// Recovery: BAD HANDLE; kRestartOm
-// FAILED OPERATION; kRestartOm or kFail
-// BUSY; An admin operation is ongoing on an object to be deleted
-// We can try again to add the create
-// return: Recovery information. See immccb.h
-int AddObjectDeleteToCcb(const SaImmCcbHandleT& ccb_handle,
+int AddDeleteToCcb(const SaImmCcbHandleT& ccb_handle,
const modelmodify::DeleteDescriptor&
delete_descriptor) {
-
+ TRACE_ENTER2("LLDTEST");
int recovery_info = modelmodify::kNotSet;
// Setup an object deleter
@@ -150,13 +144,13 @@ int AddObjectDeleteToCcb(const SaImmCcbHandleT&
ccb_handle,
base::Sleep(base::MillisToTimespec(modelmodify::kBusyWait));
continue;
} else if (ais_rc == SA_AIS_ERR_BAD_HANDLE) {
- TRACE("LLDTEST1 %s: AddObjectDeleteToCcb() Recover, %s", __FUNCTION__,
+ TRACE("LLDTEST1 %s: AddObjectDeleteToCcb() RestartOm, %s",
__FUNCTION__,
saf_error(ais_rc));
recovery_info = modelmodify::kRestartOm;
break;
- } else if (SA_AIS_ERR_FAILED_OPERATION) {
+ } else if (ais_rc == SA_AIS_ERR_FAILED_OPERATION) {
if (IsResorceAbort(ccb_handle)) {
- TRACE("LLDTEST1 %s: AddObjectDeleteToCcb(), %s, kRestartOm",
+ TRACE("LLDTEST1 %s: AddObjectDeleteToCcb(), %s, RestartOm",
__FUNCTION__, saf_error(ais_rc));
recovery_info = modelmodify::kRestartOm;
break;
@@ -167,6 +161,10 @@ int AddObjectDeleteToCcb(const SaImmCcbHandleT& ccb_handle,
recovery_info = modelmodify::kFail;
break;
}
+ } else {
+ // Unrecoverable Fail
+ recovery_info = modelmodify::kFail;
+ break;
}
}
@@ -181,5 +179,84 @@ int AddObjectDeleteToCcb(const SaImmCcbHandleT& ccb_handle,
recovery_info = modelmodify::kFail;
}
+ TRACE_LEAVE2("LLDTEST");
+ return recovery_info;
+}
+
+// Add one modify operation to a CCB
+// Recovery: BAD HANDLE; kRestartOm
+// FAILED OPERATION; kRestartOm or kFail
+// BUSY; An admin operation is ongoing on an object to be modified
+// We can try again to add the modify
+// return: Recovery information. See immccb.h
+int AddModifyToCcb(const SaImmCcbHandleT& ccb_handle,
+ const modelmodify::ModifyDescriptor&
+ modify_descriptor) {
+ TRACE_ENTER2("LLDTEST");
+ int recovery_info = modelmodify::kNotSet;
+
+ // Setup an object modifier
+ immom::ImmOmCcbObjectModify modifier(ccb_handle,
+ modify_descriptor.object_name);
+
+ // One modify operation does only modify one object but may modify several
+ // attributes in that object.
+ // Add all values for all attributes that shall be modified
+ // including the object name to the modifier
+ // Note: For each attribute the modifier needs a vector of pointers to the
+ // modify descriptors. This vector must have the same scope as the
+ // modifier. Each modify descriptor contains a value and a
+ // modification type
+ modelmodify::AttributeHandler modifications(&modifier);
+ if(modifications.AddAttributesForModification(modify_descriptor) == false) {
+ LOG_NO("LLDTEST1 %s: SetAttributeValues() Fail", __FUNCTION__);
+ recovery_info = modelmodify::kFail;
+ }
+
+ if (recovery_info == modelmodify::kNotSet) {
+ // Add the modification request to the CCB. Try gain if BUSY
+ base::Timer busy_timer(modelmodify::kBusyTimeout);
+ while (busy_timer.is_timeout() != true) {
+ if (modifier.AddObjectModifyToCcb() == false) {
+ SaAisErrorT ais_rc = modifier.ais_error();
+ if (ais_rc == SA_AIS_ERR_BUSY) {
+ base::Sleep(base::MillisToTimespec(modelmodify::kBusyWait));
+ continue;
+ } else if (ais_rc == SA_AIS_ERR_BAD_HANDLE) {
+ TRACE("LLDTEST1 %s: AddObjectModifyToCcb() RestartOm, %s",
__FUNCTION__,
+ saf_error(ais_rc));
+ recovery_info = modelmodify::kRestartOm;
+ break;
+ } else if (ais_rc == SA_AIS_ERR_FAILED_OPERATION) {
+ if (IsResorceAbort(ccb_handle)) {
+ TRACE("LLDTEST1 %s: AddObjectModifyToCcb(), %s, RestartOm",
+ __FUNCTION__, saf_error(ais_rc));
+ recovery_info = modelmodify::kRestartOm;
+ break;
+ } else {
+ // Unrecoverable Fail
+ LOG_NO("LLDTEST1 %s: AddObjectModifyToCcb() Fail, %s",
__FUNCTION__,
+ saf_error(ais_rc));
+ recovery_info = modelmodify::kFail;
+ break;
+ }
+ }
+ } else {
+ // Unrecoverable Fail
+ recovery_info = modelmodify::kFail;
+ }
+
+ // Add Modify to CCB Success
+ recovery_info = modelmodify::kContinue;
+ break;
+ }
+ if ((busy_timer.is_timeout() == true) &&
+ (recovery_info == modelmodify::kNotSet)) {
+ LOG_NO("LLDTEST %s: AddObjectModifyToCcb() Fail, BUSY timeout",
+ __FUNCTION__);
+ recovery_info = modelmodify::kFail;
+ }
+ }
return recovery_info;
+ TRACE_LEAVE2("LLDTEST");
}
diff --git a/src/smf/smfd/imm_modify_config/add_operation_to_ccb.h
b/src/smf/smfd/imm_modify_config/add_operation_to_ccb.h
index 73a5e2d13..327b24894 100644
--- a/src/smf/smfd/imm_modify_config/add_operation_to_ccb.h
+++ b/src/smf/smfd/imm_modify_config/add_operation_to_ccb.h
@@ -46,7 +46,7 @@ bool IsResorceAbort(const SaImmCcbHandleT& ccbHandle);
// BUSY; An admin operation is ongoing on an object to be deleted
// We can try again to add the create
// return: Recovery information. See immccb.h
-int AddObjectCreateToCcb(const SaImmCcbHandleT& ccb_handle,
+int AddCreateToCcb(const SaImmCcbHandleT& ccb_handle,
const modelmodify::CreateDescriptor&
create_descriptor);
@@ -56,9 +56,18 @@ int AddObjectCreateToCcb(const SaImmCcbHandleT& ccb_handle,
// BUSY; An admin operation is ongoing on an object to be deleted
// We can try again to add the create
// return: Recovery information. See immccb.h
-int AddObjectDeleteToCcb(const SaImmCcbHandleT& ccb_handle,
+int AddDeleteToCcb(const SaImmCcbHandleT& ccb_handle,
const modelmodify::DeleteDescriptor&
delete_descriptor);
+// Add one modify operation to a CCB
+// Recovery: BAD HANDLE; kRestartOm
+// FAILED OPERATION; kRestartOm or kFail
+// BUSY; An admin operation is ongoing on an object to be modified
+// We can try again to add the modify
+// return: Recovery information. See immccb.h
+int AddModifyToCcb(const SaImmCcbHandleT& ccb_handle,
+ const modelmodify::ModifyDescriptor&
+ modify_descriptor);
#endif /* IMM_API_H */
diff --git a/src/smf/smfd/imm_modify_config/attribute.cc
b/src/smf/smfd/imm_modify_config/attribute.cc
index 28dc6b76f..72d5e8828 100644
--- a/src/smf/smfd/imm_modify_config/attribute.cc
+++ b/src/smf/smfd/imm_modify_config/attribute.cc
@@ -99,83 +99,117 @@ static bool StringToNumericValue(const std::string&
str_value,
return rc;
}
-bool AttributeHandler::AddAttributes(const CreateDescriptor&
+// ----------------------
+// class AttributeHandler
+// ----------------------
+
+bool AttributeHandler::AddAttributesForObjectCreate(const CreateDescriptor&
create_descriptor) {
bool rc = true;
for (auto& attribute_descriptor : create_descriptor.attributes) {
- rc = AddAttribute(attribute_descriptor);
+ rc = AddAttribute(attribute_descriptor, Request::kCreate);
}
return rc;
}
-// Add one attribute to a creator. Store the attribute and
+bool AttributeHandler::AddAttributesForModification(const ModifyDescriptor&
+ modify_descriptor) {
+ TRACE_ENTER2("LLDTEST");
+ bool rc = true;
+ for (auto& modification : modify_descriptor.modifications) {
+ switch (modification.modification_type) {
+ case SA_IMM_ATTR_VALUES_ADD:
+ rc = AddAttribute(modification.attribute_descriptor,
+ Request::kModifyAdd);
+ break;
+ case SA_IMM_ATTR_VALUES_DELETE:
+ rc = AddAttribute(modification.attribute_descriptor,
+ Request::kModifyDelete);
+ break;
+ case SA_IMM_ATTR_VALUES_REPLACE:
+ rc = AddAttribute(modification.attribute_descriptor,
+ Request::kModifyReplace);
+ break;
+ default:
+ LOG_NO("LLDTEST %s: Invalid modification_type", __FUNCTION__);
+ rc = false;
+ break;
+ }
+ }
+
+ TRACE_LEAVE2("LLDTEST");
+ return rc;
+}
+
+// Add one attribute to a creator or a modifier. Store the attribute and
// its values until this object goes out of scope
+// The request holds information about what to do with the attribute
// Return false if fail
-bool AttributeHandler::AddAttribute(const AttributeDescriptor& attribute) {
+bool AttributeHandler::AddAttribute(const AttributeDescriptor& attribute,
+ Request request) {
+ TRACE_ENTER2("LLDTEST");
+
bool rc = true;
SaImmValueTypeT value_type = attribute.value_type;
switch (value_type) {
case SA_IMM_ATTR_SAINT32T:
- rc = StoreNumericAttribute<SaInt32T>(attribute);
+ rc = StoreNumericAttribute<SaInt32T>(attribute, request);
break;
case SA_IMM_ATTR_SAUINT32T:
- rc = StoreNumericAttribute<SaUint32T>(attribute);
+ rc = StoreNumericAttribute<SaUint32T>(attribute, request);
break;
case SA_IMM_ATTR_SAINT64T:
- rc = StoreNumericAttribute<SaInt64T>(attribute);
+ rc = StoreNumericAttribute<SaInt64T>(attribute, request);
break;
case SA_IMM_ATTR_SAUINT64T:
- rc = StoreNumericAttribute<SaUint64T>(attribute);
+ rc = StoreNumericAttribute<SaUint64T>(attribute, request);
break;
case SA_IMM_ATTR_SATIMET:
- rc = StoreNumericAttribute<CppSaTimeT>(attribute);
+ rc = StoreNumericAttribute<CppSaTimeT>(attribute, request);
// rc = StoreTimeTAttribute(attribute);
break;
case SA_IMM_ATTR_SAFLOATT:
- rc = StoreNumericAttribute<SaFloatT>(attribute);
+ rc = StoreNumericAttribute<SaFloatT>(attribute, request);
break;
case SA_IMM_ATTR_SADOUBLET:
- rc = StoreNumericAttribute<SaDoubleT>(attribute);
+ rc = StoreNumericAttribute<SaDoubleT>(attribute, request);
break;
case SA_IMM_ATTR_SASTRINGT: {
- std::unique_ptr<SetAttribute> CreatorAttribute =
- std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
- CreatorAttribute->SetAttributeValues(attribute.attribute_name,
- attribute.values_as_strings);
- set_attributesp_.push_back(std::move(CreatorAttribute));
+ StoreStringAttribute(attribute, request);
break;
}
case SA_IMM_ATTR_SANAMET:
- StoreSaNametAttribute(attribute);
+ StoreSaNametAttribute(attribute, request);
break;
case SA_IMM_ATTR_SAANYT:
- StoreSaAnytAttribute(attribute);
+ StoreSaAnytAttribute(attribute, request);
break;
default:
break;
}
+ TRACE_LEAVE2("LLDTEST");
return rc;
}
// Convert all values as a string for an attribute to numeric values.
// Create a SetAttribute object and give that object the attribute name and its
// numeric values. The SetAttribute object will store the attribute and give
-// the attribute name and values to the creator
+// the attribute name and values to a creator or a modifier
// Save the SetAttribute object in a vector so that the object will be in scope
-// until "this" object goes out of scope which shall happen when the creator
-// has given the create operation to IMM
+// until "this" object goes out of scope which shall happen when the creator or
+// modifier has given the operation to IMM
// All Store methods:
// For an attribute;
@@ -185,7 +219,8 @@ bool AttributeHandler::AddAttribute(const
AttributeDescriptor& attribute) {
// - Store the SetAttribute object
template<typename T>
bool AttributeHandler::
-StoreNumericAttribute(const AttributeDescriptor& attribute) {
+StoreNumericAttribute(const AttributeDescriptor& attribute, Request request) {
+ TRACE_ENTER2("LLDTEST");
bool rc = true;
SaImmValueTypeT value_type = attribute.value_type;
T numeric_value{0};
@@ -201,17 +236,25 @@ StoreNumericAttribute(const AttributeDescriptor&
attribute) {
num_values.push_back(numeric_value);
}
if (rc == true) {
- // Store the attribute for the creator and give it to the creator
- std::unique_ptr<SetAttribute> CreatorAttribute =
- std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
- CreatorAttribute->SetAttributeValues(attribute.attribute_name, num_values);
- set_attributesp_.push_back(std::move(CreatorAttribute));
+ // Store the attribute give it to an attribute setter
+ std::unique_ptr<SetAttribute> AnAttribute;
+ if (request == Request::kCreate) {
+ AnAttribute = std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
+ } else {
+ AnAttribute =
+ std::unique_ptr<SetAttribute>(new SetAttribute(modifier_, request));
+ }
+ AnAttribute->SetAttributeValues(attribute.attribute_name, num_values);
+ set_attributesp_.push_back(std::move(AnAttribute));
}
+
+ TRACE_LEAVE2("LLDTEST");
return rc;
}
void AttributeHandler::
-StoreSaNametAttribute(const AttributeDescriptor& attribute) {
+StoreSaNametAttribute(const AttributeDescriptor& attribute, Request request) {
+ TRACE_ENTER2("LLDTEST");
SaNameT name_value;
std::vector<SaNameT> name_values;
for (auto& value_str : attribute.values_as_strings) {
@@ -219,14 +262,22 @@ StoreSaNametAttribute(const AttributeDescriptor&
attribute) {
name_values.push_back(name_value);
}
- std::unique_ptr<SetAttribute> CreatorAttribute =
- std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
- CreatorAttribute->SetAttributeValues(attribute.attribute_name, name_values);
- set_attributesp_.push_back(std::move(CreatorAttribute));
+ // Store the attribute give it to an attribute setter
+ std::unique_ptr<SetAttribute> AnAttribute;
+ if (request == Request::kCreate) {
+ AnAttribute = std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
+ } else {
+ AnAttribute =
+ std::unique_ptr<SetAttribute>(new SetAttribute(modifier_, request));
+ }
+ AnAttribute->SetAttributeValues(attribute.attribute_name, name_values);
+ set_attributesp_.push_back(std::move(AnAttribute));
+ TRACE_LEAVE2("LLDTEST");
}
void AttributeHandler::
-StoreSaAnytAttribute(const AttributeDescriptor& attribute) {
+StoreSaAnytAttribute(const AttributeDescriptor& attribute, Request request) {
+ TRACE_ENTER2("LLDTEST");
// Note: For this type it is also needed to store the buffer pointed to
// from the SaAnyT structure
SaAnyT any_value;
@@ -237,12 +288,40 @@ StoreSaAnytAttribute(const AttributeDescriptor&
attribute) {
any_values.push_back(any_value);
}
- std::unique_ptr<SetAttribute> CreatorAttribute =
- std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
- CreatorAttribute->SetAttributeValues(attribute.attribute_name, any_values);
- set_attributesp_.push_back(std::move(CreatorAttribute));
+ // Store the attribute give it to an attribute setter
+ std::unique_ptr<SetAttribute> AnAttribute;
+ if (request == Request::kCreate) {
+ AnAttribute = std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
+ } else {
+ AnAttribute =
+ std::unique_ptr<SetAttribute>(new SetAttribute(modifier_, request));
+ }
+ AnAttribute->SetAttributeValues(attribute.attribute_name, any_values);
+ set_attributesp_.push_back(std::move(AnAttribute));
+ TRACE_LEAVE2("LLDTEST");
+}
+
+void AttributeHandler::
+StoreStringAttribute(const AttributeDescriptor& attribute, Request request) {
+ TRACE_ENTER2("LLDTEST");
+ // Store the attribute give it to an attribute setter
+ std::unique_ptr<SetAttribute> AnAttribute;
+ if (request == Request::kCreate) {
+ AnAttribute = std::unique_ptr<SetAttribute>(new SetAttribute(creator_));
+ } else {
+ AnAttribute =
+ std::unique_ptr<SetAttribute>(new SetAttribute(modifier_, request));
+ }
+ AnAttribute->SetAttributeValues(attribute.attribute_name,
+ attribute.values_as_strings);
+ set_attributesp_.push_back(std::move(AnAttribute));
+ TRACE_LEAVE2("LLDTEST");
}
+// ------------------
+// class SetAttribute
+// ------------------
+
// All SetAttributeValues methods:
// For each attribute type;
// - Create a Value Store object
@@ -254,6 +333,7 @@ StoreSaAnytAttribute(const AttributeDescriptor& attribute) {
// SaAnyT
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaAnyT>& any_values) {
+ TRACE_ENTER2("LLDTEST");
AnyValueStore_ =
std::unique_ptr<AnyValueStore>(new AnyValueStore);
for (auto& any_value : any_values) {
@@ -263,13 +343,27 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < AnyValueStore_->Values.size(); i++) {
AnyValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, AnyValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, AnyValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, AnyValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, AnyValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, AnyValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaAnyT: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
// SaNameT
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaNameT>& name_values) {
+ TRACE_ENTER2("LLDTEST");
NameValueStore_ =
std::unique_ptr<NameValueStore>(new NameValueStore);
for (auto& name_value : name_values) {
@@ -279,13 +373,27 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < NameValueStore_->Values.size(); i++) {
NameValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, NameValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, NameValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, NameValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, NameValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, NameValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaNameT: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
// SaUint32T
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaUint32T>& num_values) {
+ TRACE_ENTER2("LLDTEST");
Uint32ValueStore_ =
std::unique_ptr<Uint32ValueStore>(new Uint32ValueStore);
for (auto& num_value : num_values) {
@@ -295,12 +403,33 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < Uint32ValueStore_->Values.size(); i++) {
Uint32ValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, Uint32ValueStore_->Values_p);
+
+ LOG_NO("LLDTEST4 %s: Set value name '%s'", __FUNCTION__, name.c_str());
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, Uint32ValueStore_->Values_p);
+ LOG_NO("LLDTEST4 %s: Adding value %u for create", __FUNCTION__,
+ *Uint32ValueStore_->Values_p[0]);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, Uint32ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ LOG_NO("LLDTEST4 %s: Adding value %u for modify 'Replace'", __FUNCTION__,
+ *Uint32ValueStore_->Values_p[0]);
+ modifier_->ReplaceAttributeValue(name, Uint32ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ LOG_NO("LLDTEST4 %s: Adding value %u for modify 'Delete'", __FUNCTION__,
+ *Uint32ValueStore_->Values_p[0]);
+ modifier_->DeleteAttributeValue(name, Uint32ValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaUint32T: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
// SaInt32T
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaInt32T>& num_values) {
+ TRACE_ENTER2("LLDTEST");
Int32ValueStore_ =
std::unique_ptr<Int32ValueStore>(new Int32ValueStore);
for (auto& num_value : num_values) {
@@ -310,12 +439,26 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < Int32ValueStore_->Values.size(); i++) {
Int32ValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, Int32ValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, Int32ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, Int32ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, Int32ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, Int32ValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaInt32T: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
// SaUint64T
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaUint64T>& num_values) {
+ TRACE_ENTER2("LLDTEST");
Uint64ValueStore_ =
std::unique_ptr<Uint64ValueStore>(new Uint64ValueStore);
for (auto& num_value : num_values) {
@@ -325,11 +468,25 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < Uint64ValueStore_->Values.size(); i++) {
Uint64ValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, Uint64ValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, Uint64ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, Uint64ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, Uint64ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, Uint64ValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaUint64T: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaInt64T>& num_values) {
+ TRACE_ENTER2("LLDTEST");
Int64ValueStore_ =
std::unique_ptr<Int64ValueStore>(new Int64ValueStore);
for (auto& num_value : num_values) {
@@ -339,12 +496,26 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < Int64ValueStore_->Values.size(); i++) {
Int64ValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, Int64ValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, Int64ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, Int64ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, Int64ValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, Int64ValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaInt64T: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
// SaFloatT
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaFloatT>& num_values) {
+ TRACE_ENTER2("LLDTEST");
FloatValueStore_ =
std::unique_ptr<FloatValueStore>(new FloatValueStore);
for (auto& num_value : num_values) {
@@ -354,12 +525,26 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < FloatValueStore_->Values.size(); i++) {
FloatValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, FloatValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, FloatValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, FloatValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, FloatValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, FloatValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaFloatT: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
// SaDoubleT
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<SaDoubleT>& num_values) {
+ TRACE_ENTER2("LLDTEST");
DoubleValueStore_ =
std::unique_ptr<DoubleValueStore>(new DoubleValueStore);
for (auto& num_value : num_values) {
@@ -369,7 +554,20 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < DoubleValueStore_->Values.size(); i++) {
DoubleValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, DoubleValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, DoubleValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, DoubleValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, DoubleValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, DoubleValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s SaDoubleT: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
// SaTimeT
@@ -378,6 +576,7 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
// given to the creator API (see SetAttributeValue and TimeValueStore)
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<CppSaTimeT>& time_values) {
+ TRACE_ENTER2("LLDTEST");
TimeValueStore_ =
std::unique_ptr<TimeValueStore>(new TimeValueStore);
for (auto& num_value : time_values) {
@@ -387,11 +586,25 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < TimeValueStore_->Values.size(); i++) {
TimeValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, TimeValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, TimeValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, TimeValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, TimeValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, TimeValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s CppSaTimeT: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
void SetAttribute::SetAttributeValues(const std::string& name,
const std::vector<std::string>& str_values) {
+ TRACE_ENTER2("LLDTEST");
StringValueStore_ =
std::unique_ptr<StringValueStore>(new StringValueStore);
for (auto& str_value : str_values) {
@@ -401,5 +614,18 @@ void SetAttribute::SetAttributeValues(const std::string&
name,
for (size_t i = 0; i < StringValueStore_->Values.size(); i++) {
StringValueStore_->Values_p.push_back(v_ptr++);
}
- creator_->SetAttributeValue(name, StringValueStore_->Values_p);
+
+ if (request_ == Request::kCreate) {
+ creator_->SetAttributeValue(name, StringValueStore_->Values_p);
+ } else if (request_ == Request::kModifyAdd) {
+ modifier_->AddAttributeValue(name, StringValueStore_->Values_p);
+ } else if (request_ == Request::kModifyReplace) {
+ modifier_->ReplaceAttributeValue(name, StringValueStore_->Values_p);
+ } else if (request_ == Request::kModifyDelete) {
+ modifier_->DeleteAttributeValue(name, StringValueStore_->Values_p);
+ } else {
+ LOG_NO("LLDTEST %s string: Fail, The type of request is not set",
+ __FUNCTION__);
+ }
+ TRACE_LEAVE2("LLDTEST");
}
diff --git a/src/smf/smfd/imm_modify_config/attribute.h
b/src/smf/smfd/imm_modify_config/attribute.h
index 41112d1d6..7cb0e316c 100644
--- a/src/smf/smfd/imm_modify_config/attribute.h
+++ b/src/smf/smfd/imm_modify_config/attribute.h
@@ -122,26 +122,34 @@ struct AnyValueStore {
std::vector<SaAnyT*> Values_p;
};
+// Attributes are used with different types of operations
+enum class Request {
+ kNotSet,
+ kCreate,
+ kModifyAdd,
+ kModifyReplace,
+ kModifyDelete
+};
+
// Adds one attribute to a creator
// Used by class Attribute. Class SAttribute must see to that all objects of
// this class does not go out of scope until an object of class Attribute goes
// out of scope
class SetAttribute {
public:
- explicit SetAttribute(immom::ImmOmCcbObjectCreate* creator)
- : Uint32ValueStore_(nullptr),
- Int32ValueStore_(nullptr),
- Int64ValueStore_(nullptr),
- Uint64ValueStore_(nullptr),
- TimeValueStore_(nullptr),
- FloatValueStore_(nullptr),
- DoubleValueStore_(nullptr),
- StringValueStore_(nullptr),
- NameValueStore_(nullptr),
- AnyValueStore_(nullptr),
- creator_(creator) {}
+ explicit SetAttribute(immom::ImmOmCcbObjectCreate* creator) : SetAttribute()
+ {
+ creator_ = creator;
+ request_ = Request::kCreate;
+ }
+ explicit SetAttribute(immom::ImmOmCcbObjectModify* modifier, Request request)
+ : SetAttribute()
+ {
+ modifier_ = modifier;
+ request_ = request;
+ }
- // Store one attribute of a given type and add it to a creator
+ // Store one attribute of a given type and add it to a creator or a modifier
// The values are stored in a vector and another vector with pointers to the
// values is created. It is the pointer vector that is the in parameter for
// the creator
@@ -171,6 +179,22 @@ class SetAttribute {
const std::vector<SaAnyT>& any_values);
private:
+ // Constructor for initializing variables only
+ SetAttribute()
+ : Uint32ValueStore_(nullptr),
+ Int32ValueStore_(nullptr),
+ Int64ValueStore_(nullptr),
+ Uint64ValueStore_(nullptr),
+ TimeValueStore_(nullptr),
+ FloatValueStore_(nullptr),
+ DoubleValueStore_(nullptr),
+ StringValueStore_(nullptr),
+ NameValueStore_(nullptr),
+ AnyValueStore_(nullptr),
+ creator_(nullptr),
+ modifier_(nullptr),
+ request_(Request::kNotSet) {}
+
// Numeric
std::unique_ptr<Uint32ValueStore> Uint32ValueStore_;
std::unique_ptr<Int32ValueStore> Int32ValueStore_;
@@ -189,6 +213,8 @@ class SetAttribute {
immom::ImmOmCcbObjectCreate* creator_;
+ immom::ImmOmCcbObjectModify* modifier_;
+ Request request_;
DELETE_COPY_AND_MOVE_OPERATORS(SetAttribute);
};
@@ -210,23 +236,38 @@ class SetAttribute {
class AttributeHandler {
public:
explicit AttributeHandler(immom::ImmOmCcbObjectCreate* creator)
- : creator_(creator) {}
+ : creator_(creator), modifier_(nullptr) {}
+ explicit AttributeHandler(immom::ImmOmCcbObjectModify* modifier)
+ : creator_(nullptr), modifier_(modifier) {}
// Add all attributes in a create descriptor to a creator
- bool AddAttributes(const CreateDescriptor& create_descriptor);
+ bool AddAttributesForObjectCreate(const CreateDescriptor& create_descriptor);
+
+ // Add all attributes in a modify descriptor
+ // Note that each attribute has an AttributeModifyDescriptor which contains
+ // Information about modification type an an AttributeDescriptor
+ bool AddAttributesForModification(const ModifyDescriptor& modify_descriptor);
private:
- bool AddAttribute(const AttributeDescriptor& attribute);
+ bool AddAttribute(const AttributeDescriptor& attribute, Request request);
template<typename T>
- bool StoreNumericAttribute(const AttributeDescriptor& attribute);
+ bool StoreNumericAttribute(const AttributeDescriptor& attribute,
+ Request request);
+
+ void StoreSaNametAttribute(const AttributeDescriptor& attribute,
+ Request request);
- void StoreSaNametAttribute(const AttributeDescriptor& attribute);
+ void StoreSaAnytAttribute(const AttributeDescriptor& attribute,
+ Request request);
- void StoreSaAnytAttribute(const AttributeDescriptor& attribute);
+ void StoreStringAttribute(const AttributeDescriptor& attribute,
+ Request request);
std::vector<std::unique_ptr<SetAttribute>> set_attributesp_;
immom::ImmOmCcbObjectCreate* creator_;
+ immom::ImmOmCcbObjectModify* modifier_;
+ SaImmAttrModificationTypeT modification_type_;
DELETE_COPY_AND_MOVE_OPERATORS(AttributeHandler);
};
diff --git a/src/smf/smfd/imm_modify_config/immccb.cc
b/src/smf/smfd/imm_modify_config/immccb.cc
index 9524aecb8..e52d6b9e6 100644
--- a/src/smf/smfd/imm_modify_config/immccb.cc
+++ b/src/smf/smfd/imm_modify_config/immccb.cc
@@ -59,9 +59,9 @@ using namespace modelmodify;
//-------------------------
// The global instance number
-std::atomic<unsigned int> ObjectModification::next_instance_number_{1};
+std::atomic<unsigned int> ModelModification::next_instance_number_{1};
-ObjectModification::ObjectModification()
+ModelModification::ModelModification()
: imm_om_handle_(nullptr),
imm_ccb_handle_(nullptr),
imm_ao_handle_(nullptr),
@@ -75,14 +75,14 @@ ObjectModification::ObjectModification()
std::to_string(instance_number_);
}
-ObjectModification::~ObjectModification() {
+ModelModification::~ModelModification() {
// If an OM handle exists, cleanup the CCB handling by finalizing the handle
// Note that releaseOwnershipFinalize must be set when creating an OM admin
// owner handle so that admin ownership is released
FinalizeHandles();
}
-bool ObjectModification::DoModification(CcbDescriptor modifications) {
+bool ModelModification::DoModelModification(CcbDescriptor modifications) {
TRACE_ENTER2("LLDTEST");
bool return_status = false;
int recovery_info = kNotSet;
@@ -117,8 +117,16 @@ bool ObjectModification::DoModification(CcbDescriptor
modifications) {
continue;
}
- // TODO(Lennart)
// AddModifications. Request modifications of exiting IMM objects
+ recovery_info = AddModifies(modifications.modify_descriptors);
+ if (recovery_info == kFail) {
+ LOG_NO("LLDTEST %s: AddModifies() Fail", __FUNCTION__);
+ break;
+ } else if (recovery_info == kRestartOm) {
+ TRACE("LLDTEST %s: AddModifies() Restart", __FUNCTION__);
+ LOG_NO("LLDTEST6 %s: AddModifies() Restart", __FUNCTION__);
+ continue;
+ }
// AddDeletes. Delete IMM objects
recovery_info = AddDeletes(modifications.delete_descriptors);
@@ -136,7 +144,7 @@ bool ObjectModification::DoModification(CcbDescriptor
modifications) {
LOG_NO("LLDTEST %s: ApplyModifications() Fail", __FUNCTION__);
break;
} else if (recovery_info == kRestartOm) {
- TRACE("LLDTEST %s: ApplyModifications() Retry", __FUNCTION__);
+ TRACE("LLDTEST %s: ApplyModifications() Restart", __FUNCTION__);
continue;
}
@@ -160,7 +168,7 @@ bool ObjectModification::DoModification(CcbDescriptor
modifications) {
// Note1: Handle objects are created and private handle pointers are filled in
// Note2: No admin ownership is set here
// Return: Recovery information. See Private constants
-int ObjectModification::CreateHandles() {
+int ModelModification::CreateHandles() {
TRACE_ENTER2("LLDTEST");
int recovery_info = kNotSet;
@@ -201,7 +209,7 @@ int ObjectModification::CreateHandles() {
// Recovery: No AIS return code except TRY AGAIN is valid for retry
// Output: A valid OM handle. An OM handle object is created
// Return: Recovery information. See Private constants
-int ObjectModification::CreateObjectManager() {
+int ModelModification::CreateObjectManager() {
TRACE_ENTER2("LLDTEST");
int recovery_info = kNotSet;
if (imm_om_handle_ == nullptr) {
@@ -215,10 +223,6 @@ int ObjectModification::CreateObjectManager() {
}
bool return_state = imm_om_handle_->InitializeHandle();
- // TODO(Lennart) This is an example of how to fill in error info. May be
- // done in other places where IMM APIs are used, but do we really need this?
- error_info_.ais_error = imm_om_handle_->ais_error();
- error_info_.function_name = "saImmOmInitialize";
if (return_state == false) {
// No recovery is possible
LOG_NO("LLDTEST %s: OM-handle, InitializeHandle(), Fail", __FUNCTION__);
@@ -240,7 +244,7 @@ int ObjectModification::CreateObjectManager() {
// Output: A valid Admin Owner (AO) handle. An admin owner handle object and
// an Admin Owner Set object is created
// Return: Recovery information. See Private constants
-int ObjectModification::CreateAdminOwner() {
+int ModelModification::CreateAdminOwner() {
TRACE_ENTER2("LLDTEST");
int recovery_info = kNotSet;
if (imm_ao_handle_ == nullptr) {
@@ -277,7 +281,7 @@ int ObjectModification::CreateAdminOwner() {
// Recovery: BAD HANDLE; Restart CCB handling
// Output: A valid CCB handle. A CCB handle object is created
// Return: Recovery information. See Private constants
-int ObjectModification::CreateCcb() {
+int ModelModification::CreateCcb() {
TRACE_ENTER2("LLDTEST");
int recovery_info = kNotSet;
if (imm_ccb_handle_ == nullptr) {
@@ -305,7 +309,7 @@ int ObjectModification::CreateCcb() {
}
// Finalize all handles. Return code does not matter here
-void ObjectModification::FinalizeHandles() {
+void ModelModification::FinalizeHandles() {
TRACE_ENTER2("LLDTEST");
if (imm_om_handle_ != nullptr) {
// If an OM handle object exists the OM handle owned by the object shall be
@@ -332,7 +336,7 @@ void ObjectModification::FinalizeHandles() {
// a cluster wide resource. Others trying to become owner of the
// object(s) will fail with EXIST
// Return: Recovery information. See Private constants
-int ObjectModification::AdminOwnerSet(std::vector<std::string>& objects,
+int ModelModification::AdminOwnerSet(std::vector<std::string>& objects,
SaImmScopeT scope) {
TRACE_ENTER2("LLDTEST2");
@@ -349,10 +353,7 @@ int
ObjectModification::AdminOwnerSet(std::vector<std::string>& objects,
}
// Set objects to become admin owner of
- TRACE("LLDTEST2 %s: Becoming admin owner of the following objects:",
- __FUNCTION__);
for (auto& object : objects) {
- TRACE("LLDTEST2 %s: Object '%s'", __FUNCTION__, object.c_str());
if (object.empty()) {
// Do not add empty strings (IMM root)
continue;
@@ -377,7 +378,8 @@ int
ObjectModification::AdminOwnerSet(std::vector<std::string>& objects,
base::Sleep(base::MillisToTimespec(kExistWait));
continue;
} else if (ais_rc == SA_AIS_ERR_BAD_HANDLE) {
- TRACE("LLDTEST2 %s: SetAdminOwner() Restart", __FUNCTION__);
+ TRACE("LLDTEST2 %s: SetAdminOwner() Restart, %s", __FUNCTION__,
+ saf_error(ais_rc));
recovery_info = kRestartOm;
break;
} else {
@@ -401,90 +403,24 @@ int
ObjectModification::AdminOwnerSet(std::vector<std::string>& objects,
return recovery_info;
}
-#if 0 // TODO(Lennart) Not used so it can be removed
-// Release admin ownership that was previously set using AdminOwnerSet(...)
-// Recovery: BAD_HANDLE; Nothing to do. In this case admin ownership is
-// released
-// BUSY; An admin operation is ongoing on one of the objects
-// belonging to this admin owner. We can try again
-int ObjectModification::AdminOwnerRelease(void) {
- TRACE_ENTER2("LLDTEST21");
-
- // TODO(Lennart) Remove this function. It is never needed. The admin owner
- // shall not be released until the CCB is applied. The admin owner will be
- // released when the om handle is finalized (note that the
- // releaseOwnershipOnFinalize flag must be set to true. This is done by
- // default when the admin owner is created)
- // For now this function is dummy
- return kContinue;
-
-
- if (imm_ao_owner_set_ == nullptr) {
- // Should never happen
- LOG_ER("LLDTEST21 %s: No admin owner handle is created", __FUNCTION__);
- return kFail;
- }
-
- // Release this Admin Owner
- // An object is a cluster global resource. It is not possible to release
- // admin ownership if there is an ongoing admin operation where this owner is
- // used. Wait a reasonable time for the resource to be released.
- // Note: This should in practice not be possible in this context since this
- // admin owner is "owned" and used by this class only
- base::Timer busy_timer(kBusyTimeout);
- SaAisErrorT ais_rc = SA_AIS_OK;
- int recovery_info = kNotSet;
-
- while (busy_timer.is_timeout() == false) {
- if (imm_ao_owner_set_->ReleaseAdminOwner() == false) {
- ais_rc = imm_ao_owner_set_->ais_error();
- if (ais_rc == SA_AIS_ERR_BAD_HANDLE) {
- // This Admin owner is already released, no error
- recovery_info = kContinue;
- break;
- } else if (ais_rc == SA_AIS_ERR_BUSY) {
- TRACE("LLDTEST21 %s: SA_AIS_ERR_BUSY", __FUNCTION__);
- base::Sleep(base::MillisToTimespec(kBusyWait));
- continue;
- } else {
- LOG_NO("LLDTEST21 %s: ReleaseAdminOwner() Fail, %s", __FUNCTION__,
- saf_error(ais_rc));
- recovery_info = kFail;
- break;
- }
- }
-
- recovery_info = kContinue;
- break;
- }
- if ((busy_timer.is_timeout() == true) && (recovery_info == kNotSet)) {
- LOG_NO("LLDTEST21 %s: ReleaseAdminOwner() Fail, BUSY timeout",
- __FUNCTION__);
- recovery_info = kFail;
- }
-
- imm_ao_owner_set_->ClearObjectNames();
- TRACE_LEAVE2("LLDTEST21");
- return recovery_info;
-}
-#endif
-
// Add create requests for all objects to be created
// Set admin ownership for parent to all objects to be created with scope
// SA_IMM_ONE.
// Add all create operations to the CCB
-// Note1: We have to be owner of the parent
+// Note1: We have to be owner of the parent(s)
// Note2: It is not a problem to set admin ownership of an object that already
// has an admin owner if the same admin owner name is used, meaning that
// this is not needed to check
// Recovery: BAD HANDLE; Restart CCB handling
// FAILED OPERATION; Restart CCB handling
// Return: Recovery information
-int ObjectModification::AddCreates(std::vector<CreateDescriptor>&
+int ModelModification::AddCreates(std::vector<CreateDescriptor>&
create_descriptors) {
TRACE_ENTER2("LLDTEST");
int recovery_info = kNotSet;
+ // TODO(Lennart) The code below for setting admin owner is the same (almost)
+ // for all configuration operations (redundant). Fix
// Do this for all create descriptors
for (auto& create_descriptor : create_descriptors) {
if (create_descriptor.parent_name.empty() == false) {
@@ -504,38 +440,20 @@ int
ObjectModification::AddCreates(std::vector<CreateDescriptor>&
// Add the object create request to the ccb:
recovery_info = AddCreate(create_descriptor);
- if (recovery_info != kContinue) {
- TRACE("LLDTEST %s: AddCreate() Recovery Info %s",
- __FUNCTION__, RecoveryTxt(recovery_info));
- }
-
-#if 0 // TODO(Lennart) Shall be done after CCB Apply and is done when
- // OM Finalize is done so this code can be removed
- // Cleanup admin ownership
- // We shall always try to do this if an admin owner was set
- int release_recovery_info = AdminOwnerRelease();
- if (recovery_info != kContinue) {
- // If the previous AddCreate was not successful then recovery info from
- // AdminOwnerRelease is not relevant. We must break based on AddCreate
- // recovery info.
- break;
- }
-
- if (release_recovery_info == kFail) {
- LOG_NO("LLDTEST %s: AdminOwnerRelease() Fail", __FUNCTION__);
+ if (recovery_info == kFail) {
+ LOG_NO("LLDTEST %s: AddCreate() Fail", __FUNCTION__);
break;
- } else if (release_recovery_info == kRestartOm) {
- TRACE("LLDTEST %s: AdminOwnerRelease() Restart", __FUNCTION__);
+ } else if (recovery_info == kRestartOm) {
+ TRACE("LLDTEST %s: AddCreate() Restart", __FUNCTION__);
break;
}
-#endif
} // For all create descriptors
if (recovery_info == kNotSet) {
- // All creates are added, no recovery needed
+ // No creates are added, no recovery needed
recovery_info = kContinue;
}
- TRACE_LEAVE2("LLDTEST, recovery_info = %s", RecoveryTxt(recovery_info));
+ TRACE_LEAVE2("LLDTEST");
return recovery_info;
}
@@ -544,12 +462,11 @@ int
ObjectModification::AddCreates(std::vector<CreateDescriptor>&
// Add all attributes
// Add the create request to the ccb
// Return: Recovery information
-int ObjectModification::AddCreate(CreateDescriptor& create_descriptor) {
+int ModelModification::AddCreate(CreateDescriptor& create_descriptor) {
TRACE_ENTER2("LLDTEST");
- int recovery_info = kNotSet;
- SaImmCcbHandleT ccb_handle = imm_ccb_handle_->GetHandle();
- recovery_info = AddObjectCreateToCcb(ccb_handle, create_descriptor);
+ SaImmCcbHandleT ccb_handle = imm_ccb_handle_->GetHandle();
+ int recovery_info = AddCreateToCcb(ccb_handle, create_descriptor);
TRACE_LEAVE2("LLDTEST");
return recovery_info;
@@ -558,14 +475,14 @@ int ObjectModification::AddCreate(CreateDescriptor&
create_descriptor) {
// Add delete requests for all objects to be deleted
// Set admin ownership for objects to be deleted with scope SA_IMM_SUBTREE.
// Add all delete operations to the CCB
-// Note1: We have to be owner of the object and the sub tree
+// Note1: We have to be owner of the object(s) and the sub tree
// Note2: It is not a problem to set admin ownership of an object that already
// has an admin owner if the same admin owner name is used, meaning that
// this is not needed to check
// Recovery: BAD HANDLE; Restart CCB handling
// FAILED OPERATION; Restart CCB handling if resource abort
// Return: Recovery information
-int ObjectModification::AddDeletes(std::vector<DeleteDescriptor>&
+int ModelModification::AddDeletes(std::vector<DeleteDescriptor>&
delete_descriptors) {
TRACE_ENTER2("LLDTEST");
int recovery_info = kNotSet;
@@ -585,46 +502,28 @@ int
ObjectModification::AddDeletes(std::vector<DeleteDescriptor>&
break;
}
} else {
- LOG_NO("LLDTEST %s: AddDeletes() Fail, No object to delete",
+ LOG_NO("LLDTEST %s: AddDeletes() Fail, Object name is missing",
__FUNCTION__);
recovery_info = kFail;
+ break;
}
// Add the object delete request to the ccb:
recovery_info = AddDelete(delete_descriptor);
- if (recovery_info != kContinue) {
- TRACE("LLDTEST %s: AddDelete() Recovery Info %s",
- __FUNCTION__, RecoveryTxt(recovery_info));
- }
-
-#if 0 // TODO(Lennart) Shall be done after CCB Apply and is done when
- // OM Finalize is done so this code can be removed
- // Cleanup admin ownership
- // Cleanup admin ownership
- // We shall always try to do this if an admin owner was set
- int release_recovery_info = AdminOwnerRelease();
- if (recovery_info != kContinue) {
- // If the previous AddDelete was not successful then recovery info from
- // AdminOwnerRelease is not relevant. We must break based on AddDelete
- // recovery info.
- break;
- }
-
- if (release_recovery_info == kFail) {
- LOG_NO("LLDTEST %s: AdminOwnerRelease() Fail", __FUNCTION__);
+ if (recovery_info == kFail) {
+ LOG_NO("LLDTEST %s: AddDelete() Fail", __FUNCTION__);
break;
- } else if (release_recovery_info == kRestartOm) {
- TRACE("LLDTEST %s: AdminOwnerRelease() Restart", __FUNCTION__);
+ } else if (recovery_info == kRestartOm) {
+ TRACE("LLDTEST %s: AddDelete() Restart", __FUNCTION__);
break;
}
-#endif
} // For all delete descriptors
if (recovery_info == kNotSet) {
- // All deletes are added, no recovery needed
+ // No deletes are added, no recovery needed
recovery_info = kContinue;
}
- TRACE_LEAVE2("LLDTEST, recovery_info = %s", RecoveryTxt(recovery_info));
+ TRACE_LEAVE2("LLDTEST");
return recovery_info;
}
@@ -632,25 +531,91 @@ int
ObjectModification::AddDeletes(std::vector<DeleteDescriptor>&
// Set object name
// Add the delete request to the ccb
// Return: Recovery information
-int ObjectModification::AddDelete(DeleteDescriptor& delete_descriptor) {
+int ModelModification::AddDelete(DeleteDescriptor& delete_descriptor) {
TRACE_ENTER2("LLDTEST");
- int recovery_info = kNotSet;
+
SaImmCcbHandleT ccb_handle = imm_ccb_handle_->GetHandle();
+ int recovery_info = AddDeleteToCcb(ccb_handle, delete_descriptor);
- recovery_info = AddObjectDeleteToCcb(ccb_handle, delete_descriptor);
+ TRACE_LEAVE2("LLDTEST");
+ return recovery_info;
+}
+// Add modify requests for all objects to be modified
+// Set admin ownership for all objects to be modified with scope
+// SA_IMM_ONE.
+// Add all modify operations to the CCB
+// Note1: We have to be owner of the object(s)
+// Note2: It is not a problem to set admin ownership of an object that already
+// has an admin owner if the same admin owner name is used, meaning that
+// this is not needed to check
+// Recovery: BAD HANDLE; Restart CCB handling
+// FAILED OPERATION; Restart CCB handling
+// Return: Recovery information
+int ModelModification::AddModifies(std::vector<ModifyDescriptor>&
+ modify_descriptors) {
+ TRACE_ENTER2("LLDTEST");
+ int recovery_info = kNotSet;
+ // Do this for all modify descriptors
+ for (auto& modify_descriptor : modify_descriptors) {
+ if (modify_descriptor.object_name.empty() == false) {
+ // Become admin owner of object if there is an object. If not Fail
+ std::vector<std::string> imm_objects;
+ imm_objects.push_back(modify_descriptor.object_name);
+ recovery_info = AdminOwnerSet(imm_objects, SA_IMM_ONE);
+ if (recovery_info == kFail) {
+ LOG_NO("LLDTEST %s: AdminOwnerSet() Fail", __FUNCTION__);
+ break;
+ } else if (recovery_info == kRestartOm) {
+ TRACE("LLDTEST %s: AdminOwnerSet() Restart", __FUNCTION__);
+ break;
+ }
+ } else {
+ LOG_NO("LLDTEST %s: AddModifies() Fail, Object name is missing",
+ __FUNCTION__);
+ recovery_info = kFail;
+ break;
+ }
+
+ // Add the object modify request to the ccb:
+ recovery_info = AddModify(modify_descriptor);
+ if (recovery_info == kFail) {
+ LOG_NO("LLDTEST %s: AddModify() Fail", __FUNCTION__);
+ break;
+ } else if (recovery_info == kRestartOm) {
+ TRACE("LLDTEST %s: AddModify() Restart", __FUNCTION__);
+ break;
+ }
+ } // For all modify descriptors
+
+ if (recovery_info == kNotSet) {
+ // All deletes are added, no recovery needed
+ recovery_info = kContinue;
+ }
TRACE_LEAVE2("LLDTEST");
return recovery_info;
}
+// Add one modify descriptor to the ccb
+// Set object name
+// Add the modify request to the ccb.
+// The modify request can only be for one object but may contain
+// modifications for several attributes
+int ModelModification::AddModify(ModifyDescriptor& modify_descriptor) {
+ TRACE_ENTER2("LLDTEST");
+ SaImmCcbHandleT ccb_handle = imm_ccb_handle_->GetHandle();
+ int recovery_info = AddModifyToCcb(ccb_handle, modify_descriptor);
+ TRACE_LEAVE2("LLDTEST");
+ return recovery_info;
+}
// Apply the CCB. Based on a valid CCB handle
// Recovery: BAD HANDLE; Restart CCBhandling
// FAILED OPERATION; Restart CCBhandling
-int ObjectModification::ApplyModifications() {
+int ModelModification::ApplyModifications() {
TRACE_ENTER2("LLDTEST");
int recovery_info = kNotSet;
diff --git a/src/smf/smfd/imm_modify_config/immccb.h
b/src/smf/smfd/imm_modify_config/immccb.h
index e633fd1bc..6fc71eee4 100644
--- a/src/smf/smfd/imm_modify_config/immccb.h
+++ b/src/smf/smfd/imm_modify_config/immccb.h
@@ -158,7 +158,7 @@ struct AttributeModifyDescriptor {
// Type of modification
SaImmAttrModificationTypeT modification_type;
// The attribute to be modified and the new value(s)
- AttributeDescriptor attribute;
+ AttributeDescriptor attribute_descriptor;
};
@@ -212,7 +212,7 @@ struct ModifyDescriptor {
// Full DN of the object to be modified
std::string object_name;
std::vector<AttributeModifyDescriptor> modifications;
- void AddModification(AttributeModifyDescriptor one_modification) {
+ void AddAttributeModification(AttributeModifyDescriptor one_modification) {
modifications.push_back(one_modification);
}
};
@@ -275,13 +275,13 @@ const uint64_t kExistWait = 2000; // 2 sec
inline static const char* RecoveryTxt(int recovery_info) {
switch (recovery_info) {
case modelmodify::kContinue:
- return "kContinue";
+ return "Continue";
case modelmodify::kFail:
- return "kFail";
+ return "Fail";
case modelmodify::kNotSet:
- return "kNotSet";
+ return "NotSet";
case modelmodify::kRestartOm:
- return "kRestartOm";
+ return "RestartOm";
default:
return "Unknown recovery info";
}
@@ -329,10 +329,10 @@ inline static const char* RecoveryTxt(int recovery_info) {
// // Do some other error handling...
// }
//
-class ObjectModification {
+class ModelModification {
public:
- ObjectModification();
- ~ObjectModification(); // TODO(Lennart) Finalize the Object Manager
+ ModelModification();
+ ~ModelModification(); // TODO(Lennart) Finalize the Object Manager
// Set CCB Flags
// If flag SA_IMM_CCB_REGISTERED_OI is set then an Object Implementer must
@@ -343,7 +343,7 @@ class ObjectModification {
// Returns False if an unrecoverable problem occurs. This may for example be
// a validation error
- bool DoModification(CcbDescriptor modifications);
+ bool DoModelModification(CcbDescriptor modifications);
// Get more information if DoModification return Fail
ErrorInfo GetErrorInfo(void) { return error_info_; }
@@ -356,7 +356,6 @@ class ObjectModification {
int CreateCcb(void);
int AdminOwnerSet(std::vector<std::string>& objects, SaImmScopeT scope);
- //int AdminOwnerRelease(void);
// Handle om_ccb_object_create()
int AddCreates(std::vector<CreateDescriptor>& create_descriptors);
@@ -364,6 +363,9 @@ class ObjectModification {
// Handle om_ccb_object_delete()
int AddDeletes(std::vector<DeleteDescriptor>& delete_descriptors);
int AddDelete(DeleteDescriptor& delete_descriptor);
+ // Handle om_ccb_object_modify()
+ int AddModifies(std::vector<ModifyDescriptor>& modify_descriptors);
+ int AddModify(ModifyDescriptor& modify_descriptor);
int ApplyModifications(void);
@@ -394,7 +396,7 @@ class ObjectModification {
uint64_t modification_timeout_;
SaImmCcbFlagsT ccb_flags_;
- DELETE_COPY_AND_MOVE_OPERATORS(ObjectModification);
+ DELETE_COPY_AND_MOVE_OPERATORS(ModelModification);
};
} // namespace modelmodify
diff --git a/src/smf/smfd/imm_modify_demo/ccbdemo_create.cc
b/src/smf/smfd/imm_modify_demo/ccbdemo_create.cc
index 124abe9eb..f09125db3 100644
--- a/src/smf/smfd/imm_modify_demo/ccbdemo_create.cc
+++ b/src/smf/smfd/imm_modify_demo/ccbdemo_create.cc
@@ -426,9 +426,9 @@ int main(void) {
//PrintCcbDescriptor(test_ccb);
cout << endl;
- modelmodify::ObjectModification model_modifier;
+ modelmodify::ModelModification model_modifier;
model_modifier.SetCcbFlags(0);
- if (model_modifier.DoModification(test_ccb) == false) {
+ if (model_modifier.DoModelModification(test_ccb) == false) {
cout << "DoModification() Fail" << endl;
}
diff --git a/src/smf/smfd/imm_modify_demo/ccbdemo_delete.cc
b/src/smf/smfd/imm_modify_demo/ccbdemo_delete.cc
index 534433194..f81456179 100644
--- a/src/smf/smfd/imm_modify_demo/ccbdemo_delete.cc
+++ b/src/smf/smfd/imm_modify_demo/ccbdemo_delete.cc
@@ -159,9 +159,9 @@ int main() {
delete_object.object_name = "TestObj2=1";
test_ccb.AddDelete(delete_object);
- modelmodify::ObjectModification model_modifier;
+ modelmodify::ModelModification model_modifier;
model_modifier.SetCcbFlags(0); // No OI for this class/objects of this class
- if (model_modifier.DoModification(test_ccb) == false) {
+ if (model_modifier.DoModelModification(test_ccb) == false) {
cout << "DoModification() Fail" << endl;
}
diff --git a/src/smf/smfd/imm_modify_demo/ccbdemo_modify.cc
b/src/smf/smfd/imm_modify_demo/ccbdemo_modify.cc
index 399267052..d64e31e45 100644
--- a/src/smf/smfd/imm_modify_demo/ccbdemo_modify.cc
+++ b/src/smf/smfd/imm_modify_demo/ccbdemo_modify.cc
@@ -126,7 +126,7 @@ int main() {
cout << "Become AO of the object to be modified" << endl;
immom::ImmOmAdminOwnerSet ao_setter(ao_handle.GetHandle());
ao_setter.AddObjectName("TestObj1=1,safApp=safSmfService"); // Object
- if (ao_setter.SetAdminOwner(SA_IMM_SUBTREE) == false) {
+ if (ao_setter.SetAdminOwner(SA_IMM_ONE) == false) {
cout << "AO Set Fail, " << ao_setter.ais_error_string() << endl;
return -1;
}
@@ -135,27 +135,27 @@ int main() {
cout << "Add modify operation(s) to CCB" << endl;
-// immom::ImmOmCcbObjectDelete deleter(ccb_handle.GetHandle());
-// if (deleter.AddObjectDeleteToCcb("TestObj1=1,safApp=safSmfService")
-// == false) {
-// cout << "AddObjectDeleteToCcb() Fail, " << deleter.ais_error_string()
-// << endl;
-// }
std::string object1 = "TestObj1=1,safApp=safSmfService";
//std::string object2 = "TestObj2=1";
immom::ImmOmCcbObjectModify modifier(ccb_handle.GetHandle(), object1);
// Add 10 and 20 to existing SaUint32TValues
-// AddAttributeValue(const std::string& name,
-// const std::vector<T*>& list_of_ptr_to_values);
std::vector<SaUint32T> uint32_values{10, 20};
std::vector<SaUint32T*> uint32_values_pointers;
SaUint32T* val_p = uint32_values.data();
uint32_values_pointers.push_back(val_p++);
uint32_values_pointers.push_back(val_p);
+ // Replace the SaUint32TValue with 90
+ std::vector<SaUint32T> uint32_values1{90};
+ std::vector<SaUint32T*> uint32_values_pointers1;
+ val_p = uint32_values1.data();
+ uint32_values_pointers1.push_back(val_p);
+
+
modifier.AddAttributeValue("SaUint32TValues", uint32_values_pointers);
+ modifier.ReplaceAttributeValue("SaUint32TValue", uint32_values_pointers1);
if (modifier.AddObjectModifyToCcb() == false) {
cout << "AddObjectModifyToCcb() Fail, " << modifier.ais_error_string()
<< endl;
@@ -167,14 +167,6 @@ int main() {
return -1;
}
-#if 0 // Don't do this
- cout << "Release AO using ao_setter release method" << endl;
- if (ao_setter.ReleaseAdminOwner() == false) {
- cout << "AO release Fail, " << ao_setter.ais_error_string() << endl;
- //return -1;
- }
-#endif
-
cout << "Clean up; Finalize OM handle" << endl;
om_handle.FinalizeHandle();
@@ -183,8 +175,99 @@ int main() {
#endif
#if 1 // Modifying object using modelmodify
+void PrintValues(modelmodify::ModifyDescriptor modifier) {
+ cout << "Printing a modifier:" << endl;
+
+ cout << "modifier.object_name = " << modifier.object_name << endl;
+
+ cout << "Modifications:" << endl;
+ for (auto& modification : modifier.modifications) {
+ cout << "modification.modification_type = " <<
+ modification.modification_type << endl;
+ cout << "modification.attribute_descriptor.attribute_name = " <<
+ modification.attribute_descriptor.attribute_name << endl;
+ cout << "modification.attribute_descriptor.value_type = " <<
+ modification.attribute_descriptor.value_type << endl;
+ cout << "Values:" << endl;
+ for (auto& str_value :
+ modification.attribute_descriptor.values_as_strings) {
+ cout << "str_value = " << str_value << endl;
+ }
+ }
+ cout << endl;
+}
+
int main() {
- cout << "ccb_modify" << endl;
+ cout << "Modifying an object using 'modelmodify'. Object must exist" <<
+ endl;
+ cout << "Class: ImmTestValuesConfig" << endl;
+ cout << "Modify: TestObj1=1,safApp=safSmfService" << endl << endl;
+
+#if 1// Enable trace
+ unsigned int category_mask = 0xffffffff;
+ const char* logPath = PKGLOGDIR "/osafccbdemo1";
+ if (logtrace_init("ccbdemo1", logPath, category_mask) == -1) {
+ syslog(LOG_ERR, "osafntfimcnd logtrace_init FAILED");
+ /* We allow to execute anyway. */
+ cout << "logtrace_init() Fail" << endl;
+ } else {
+ //cout << "logtrace enabled" << endl;
+ }
+#endif
+
+ // Prepare extended name
+ setenv("SA_ENABLE_EXTENDED_NAMES", "1", 1);
+ osaf_extended_name_init();
+
+ //
===========================================================================
+ // Add 10 and 20 to existing 'SaUint32TValues' attribute
+ //
===========================================================================
+
+ // 1. Attribute descriptor
+ modelmodify::AttributeDescriptor uint32_multivalue_attribute;
+ uint32_multivalue_attribute.attribute_name = "SaUint32TValues";
+ uint32_multivalue_attribute.value_type = SA_IMM_ATTR_SAUINT32T;
+ uint32_multivalue_attribute.AddValue(std::to_string(10));
+ uint32_multivalue_attribute.AddValue(std::to_string(20));
+
+ // 1. Attribute modify descriptor
+ modelmodify::AttributeModifyDescriptor uint32_multivalue_modify;
+ uint32_multivalue_modify.modification_type = SA_IMM_ATTR_VALUES_ADD;
+ uint32_multivalue_modify.attribute_descriptor = uint32_multivalue_attribute;
+
+ // 2. Attribute descriptor
+ modelmodify::AttributeDescriptor uint32_attribute;
+ uint32_attribute.attribute_name = "SaUint32TValue";
+ uint32_attribute.value_type = SA_IMM_ATTR_SAUINT32T;
+ uint32_attribute.AddValue(to_string(90));
+
+ // 2. Attribute modify descriptor
+ modelmodify::AttributeModifyDescriptor uint32_modify;
+ uint32_modify.modification_type = SA_IMM_ATTR_VALUES_REPLACE;
+ uint32_modify.attribute_descriptor = uint32_attribute;
+
+ // Add modification to the attribute modification to the modify descriptor
+ modelmodify::ModifyDescriptor modification;
+ modification.object_name = "TestObj1=1,safApp=safSmfService";
+ modification.AddAttributeModification(uint32_multivalue_modify);
+ modification.AddAttributeModification(uint32_modify);
+
+ // LLDTEST Print modifier content
+ PrintValues(modification);
+
+ // Add the modify descriptor to the ccb descriptor
+ modelmodify::CcbDescriptor model_configuration_change;
+ model_configuration_change.AddModify(modification);
+
+ // Create a modifier object and do the modification described in the
+ // ccb descriptor 'model_configuration_change'
+ modelmodify::ModelModification model_changer;
+ model_changer.SetCcbFlags(0);
+ if (model_changer.DoModelModification(model_configuration_change) == false) {
+ cout << "DoModelModification() Fail" << endl;
+ } else {
+ cout << "DoModelModification() Success" << endl;
+ }
return 0;
}
diff --git a/src/smf/smfd/imm_om_api/common/imm_attribute.h
b/src/smf/smfd/imm_om_api/common/imm_attribute.h
index a3412c876..d8c9b9bbb 100644
--- a/src/smf/smfd/imm_om_api/common/imm_attribute.h
+++ b/src/smf/smfd/imm_om_api/common/imm_attribute.h
@@ -18,9 +18,6 @@
#ifndef SRC_LOG_IMMWRP_COMMON_IMM_ATTRIBUTE_H_
#define SRC_LOG_IMMWRP_COMMON_IMM_ATTRIBUTE_H_
-#if 1 // LLDTEST
-#include <iostream>
-#endif
#include <string.h>
#include <string>
#include <vector>
diff --git a/src/smf/smfd/imm_om_api/om_ccb_object_create.h
b/src/smf/smfd/imm_om_api/om_ccb_object_create.h
index f16f1b000..656b9bfcb 100644
--- a/src/smf/smfd/imm_om_api/om_ccb_object_create.h
+++ b/src/smf/smfd/imm_om_api/om_ccb_object_create.h
@@ -119,9 +119,6 @@ class ImmOmCcbObjectCreate : public ImmBase {
private:
void FreeAllocatedMemory();
- // TODO(Lennart) LLDTEST Remove
- void traceAttrVal(SaImmAttrValuesT_2 **attribute_values);
-
//private:
std::string class_name_;
std::string parent_object_;
--
2.15.1
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel