Add new FM API methods
New API methods have been added to allow getting, setting, and clearing faults by providing both alarm_id and entity_instance_id. Changes in this commit: - For clear_fault operation, the query has been updated to allow the removal of multiple rows with a single query. The entity_instance_id parameter can now be a prefix, enabling the matching of multiple alarms with the same alarm_id. This change does not affect existing use cases. - New method get_faults_by_id_n_eid, This method allows API clients to retrieve a list of alarms that match an alarm_id and a prefix of entity_instance_id, thereby matching multiple alarms. - New method set_faults. This method accepts a list of alarms as a parameter and calls the same core set_fault function for each alarm. [PASS] Build and install packages [PASS] Remove several alarms that matches 'alarm_id', 'entity_instance_id=%' [PASS] Get list of alarms that match 'alarm_id' and 'entity_instance_id=%' [PASS] Verify that the new behavior for removing alarms does not affect previous use cases. [PASS] Test set_faults API function providing a list of alarms. Verify the alarms in the list are being created. [PASS] Enable debug mode to verify that queries are as expected. Story: 2011106 task: 50756 Change-Id: Ib9dcfa97960a5d50865133a61810681e5a09edbe Signed-off-by: fperez <fabrizio.perez@windriver.com>
This commit is contained in:
parent
05f5d63de9
commit
625e253b7c
@ -1,5 +1,5 @@
|
|||||||
#
|
#
|
||||||
# Copyright (c) 2013-2018 Wind River Systems, Inc.
|
# Copyright (c) 2013-2024 Wind River Systems, Inc.
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
@ -185,6 +185,19 @@ class FaultAPIs(FaultAPIsBase):
|
|||||||
except (RuntimeError, SystemError, TypeError):
|
except (RuntimeError, SystemError, TypeError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def set_faults(self, data):
|
||||||
|
buff_list = []
|
||||||
|
with fm_api_lock:
|
||||||
|
for alarm_data in data:
|
||||||
|
self._check_required_attributes(alarm_data)
|
||||||
|
self._validate_attributes(alarm_data)
|
||||||
|
buff = self._alarm_to_str(alarm_data)
|
||||||
|
buff_list.append(buff)
|
||||||
|
try:
|
||||||
|
return fm_core.set_fault_list(buff_list)
|
||||||
|
except (RuntimeError, SystemError, TypeError):
|
||||||
|
return None
|
||||||
|
|
||||||
def clear_fault(self, alarm_id, entity_instance_id):
|
def clear_fault(self, alarm_id, entity_instance_id):
|
||||||
with fm_api_lock:
|
with fm_api_lock:
|
||||||
sep = constants.FM_CLIENT_STR_SEP
|
sep = constants.FM_CLIENT_STR_SEP
|
||||||
@ -244,6 +257,22 @@ class FaultAPIs(FaultAPIsBase):
|
|||||||
pass
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_faults_by_id_n_eid(self, alarm_id, entity_instance_id):
|
||||||
|
with fm_api_lock:
|
||||||
|
sep = constants.FM_CLIENT_STR_SEP
|
||||||
|
buff = (sep + self._check_val(alarm_id) + sep +
|
||||||
|
self._check_val(entity_instance_id) + sep)
|
||||||
|
try:
|
||||||
|
resp = fm_core.get_by_id_n_eid(buff)
|
||||||
|
if resp:
|
||||||
|
data = []
|
||||||
|
for i in resp:
|
||||||
|
data.append(self._str_to_alarm(i))
|
||||||
|
return data
|
||||||
|
except (RuntimeError, SystemError, TypeError):
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
def get_faults_by_id(self, alarm_id):
|
def get_faults_by_id(self, alarm_id):
|
||||||
with fm_api_lock:
|
with fm_api_lock:
|
||||||
try:
|
try:
|
||||||
|
@ -81,6 +81,17 @@ def get_all(instance_id):
|
|||||||
print("No alarm returned")
|
print("No alarm returned")
|
||||||
|
|
||||||
|
|
||||||
|
def get_all_by_id_n_eid(alarm_id, instance_id):
|
||||||
|
ll = ser.get_faults_by_id_n_eid(alarm_id, instance_id)
|
||||||
|
if ll is not None:
|
||||||
|
print("Total alarm returned: %d\n"
|
||||||
|
% len(ll))
|
||||||
|
for i in ll:
|
||||||
|
print_alarm(i)
|
||||||
|
else:
|
||||||
|
print("No alarm returned")
|
||||||
|
|
||||||
|
|
||||||
def get_list(alarm_id):
|
def get_list(alarm_id):
|
||||||
ll = ser.get_faults_by_id(alarm_id)
|
ll = ser.get_faults_by_id(alarm_id)
|
||||||
if ll is not None:
|
if ll is not None:
|
||||||
@ -105,3 +116,5 @@ if __name__ == "__main__":
|
|||||||
sys.exit(del_all(sys.argv[2]))
|
sys.exit(del_all(sys.argv[2]))
|
||||||
elif sys.argv[1] == "get_list":
|
elif sys.argv[1] == "get_list":
|
||||||
sys.exit(get_list(sys.argv[2]))
|
sys.exit(get_list(sys.argv[2]))
|
||||||
|
elif sys.argv[1] == "get_list_id_eid":
|
||||||
|
sys.exit(get_all_by_id_n_eid(sys.argv[2], sys.argv[3]))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2017,2023 Wind River Systems, Inc.
|
// Copyright (c) 2017,2024 Wind River Systems, Inc.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
@ -287,7 +287,24 @@ EFmErrorT fm_set_fault(const SFmAlarmDataT *alarm,
|
|||||||
return FM_ERR_OK;
|
return FM_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears fault entries based on the specified filter.
|
||||||
|
*
|
||||||
|
* This function sends a request to the FM server which performs the
|
||||||
|
* query for the clear_fault operation.
|
||||||
|
* In addition, this allows the removal of multiple rows with a single query.
|
||||||
|
*
|
||||||
|
* **Parameters:**
|
||||||
|
* - `filter`: A pointer to an `AlarmFilter` structure. This includes `alarm_id`
|
||||||
|
* and `entity_instance_id`.
|
||||||
|
*
|
||||||
|
* **Returns:**
|
||||||
|
* - `FM_ERR_OK` if the operation was successful.
|
||||||
|
* - `FM_ERR_NOCONNECT` if the function failed to connect to the server or if the
|
||||||
|
* connection was lost during the operation.
|
||||||
|
* - Other error codes as defined in the `EFmErrorT` enumeration if the operation
|
||||||
|
* encountered other issues.
|
||||||
|
*/
|
||||||
EFmErrorT fm_clear_fault(AlarmFilter *filter) {
|
EFmErrorT fm_clear_fault(AlarmFilter *filter) {
|
||||||
|
|
||||||
CFmMutexGuard m(getAPIMutex());
|
CFmMutexGuard m(getAPIMutex());
|
||||||
@ -479,6 +496,90 @@ EFmErrorT fm_get_faults_by_id(fm_alarm_id *alarm_id,
|
|||||||
return FM_ERR_OK;
|
return FM_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves alarms based on a filter with alarm_id and
|
||||||
|
* entity_instance_id.
|
||||||
|
*
|
||||||
|
* This function sends a request to the FM server to retrieve faults
|
||||||
|
* information matching the given filter criteria.
|
||||||
|
* The entity_instance_id parameter can now be a prefix (not complete),
|
||||||
|
* enabling the matching of multiple alarms with the same alarm_id
|
||||||
|
*
|
||||||
|
* **Parameters:**
|
||||||
|
* - `filter`: A pointer to an `AlarmFilter` structure. This includes `alarm_id`
|
||||||
|
* and `entity_instance_id`.
|
||||||
|
* - `alarm`: A pointer to an array of `SFmAlarmDataT` structures where
|
||||||
|
* the retrieved alarms will be stored.
|
||||||
|
* - `max_alarms_to_get`: On input, specifies the maximum number of alarms
|
||||||
|
* to retrieve. On output, specifies the number of alarms actually retrieved.
|
||||||
|
*
|
||||||
|
* **Returns:**
|
||||||
|
* An error code indicating the result of the operation. Possible values include:
|
||||||
|
* - `FM_ERR_OK`: Operation was successful.
|
||||||
|
* - `FM_ERR_NOCONNECT`: Failed to connect to the FM core.
|
||||||
|
* - Other error codes as defined in the `EFmErrorT` enumeration.
|
||||||
|
*/
|
||||||
|
EFmErrorT fm_get_faults_by_id_n_eid(AlarmFilter *filter,
|
||||||
|
SFmAlarmDataT *alarm,
|
||||||
|
unsigned int *max_alarms_to_get) {
|
||||||
|
|
||||||
|
CFmMutexGuard m(getAPIMutex());
|
||||||
|
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
|
||||||
|
fm_check_thread_pending_request();
|
||||||
|
|
||||||
|
fm_buff_t buff;
|
||||||
|
buff.clear();
|
||||||
|
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff, EFmGetFaultsByIdnEid,
|
||||||
|
filter,sizeof(*filter));
|
||||||
|
if (erc!=FM_ERR_OK) return erc;
|
||||||
|
|
||||||
|
// if it was not correctly sent by the API, set to the expected value
|
||||||
|
if (*max_alarms_to_get == 0){
|
||||||
|
*max_alarms_to_get = DEF_MAX_ALARMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_client.write_packet(buff)) {
|
||||||
|
if (!m_client.read_packet(buff)) {
|
||||||
|
m_connected = false;
|
||||||
|
return FM_ERR_NOCONNECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr_to_hdr(buff)->msg_rc != FM_ERR_OK){
|
||||||
|
*max_alarms_to_get = 0;
|
||||||
|
EFmErrorT rc = (EFmErrorT)ptr_to_hdr(buff)->msg_rc;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t pkt_size = ptr_to_hdr(buff)->msg_size;
|
||||||
|
if (pkt_size < sizeof(uint32_t)) {
|
||||||
|
FM_ERROR_LOG("Received invalid pkt size: %u\n",pkt_size );
|
||||||
|
m_connected = false;
|
||||||
|
return FM_ERR_COMMUNICATIONS;
|
||||||
|
}
|
||||||
|
// Decrement pkt_size by the size of the length field in the header
|
||||||
|
// to get the size of the actual alarm data
|
||||||
|
pkt_size-=sizeof(uint32_t);
|
||||||
|
|
||||||
|
char *dptr = (char*)ptr_to_data(buff);
|
||||||
|
|
||||||
|
uint32_t *len = (uint32_t*)dptr;
|
||||||
|
dptr+=sizeof(uint32_t);
|
||||||
|
if (*max_alarms_to_get < *len) {
|
||||||
|
return FM_ERR_NOT_ENOUGH_SPACE;
|
||||||
|
}
|
||||||
|
if (pkt_size < (*len*sizeof(SFmAlarmDataT)) ) {
|
||||||
|
return FM_ERR_COMMUNICATIONS;
|
||||||
|
}
|
||||||
|
*max_alarms_to_get = *len;
|
||||||
|
memcpy(alarm,dptr,pkt_size);
|
||||||
|
} else {
|
||||||
|
m_connected = false;
|
||||||
|
return FM_ERR_NOCONNECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FM_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* APIs that enqueue the request and return ok for acknowledgment.
|
* APIs that enqueue the request and return ok for acknowledgment.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2017 Wind River Systems, Inc.
|
// Copyright (c) 2024 Wind River Systems, Inc.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
@ -27,6 +27,8 @@ typedef unsigned char FMBoolTypeT;
|
|||||||
|
|
||||||
#define FM_FALSE 0
|
#define FM_FALSE 0
|
||||||
|
|
||||||
|
static const size_t DEF_MAX_ALARMS (1000);
|
||||||
|
|
||||||
typedef enum{
|
typedef enum{
|
||||||
FM_ALARM_STATE_CLEAR = 0,
|
FM_ALARM_STATE_CLEAR = 0,
|
||||||
FM_ALARM_STATE_SET = 1,
|
FM_ALARM_STATE_SET = 1,
|
||||||
@ -204,6 +206,10 @@ EFmErrorT fm_get_faults(fm_ent_inst_t *inst_id, SFmAlarmDataT *alarm,
|
|||||||
EFmErrorT fm_get_faults_by_id(fm_alarm_id *alarm_id, SFmAlarmDataT *alarm,
|
EFmErrorT fm_get_faults_by_id(fm_alarm_id *alarm_id, SFmAlarmDataT *alarm,
|
||||||
unsigned int *max_alarms_to_get);
|
unsigned int *max_alarms_to_get);
|
||||||
|
|
||||||
|
EFmErrorT fm_get_faults_by_id_n_eid(AlarmFilter *filter,
|
||||||
|
SFmAlarmDataT *alarm,
|
||||||
|
unsigned int *max_alarms_to_get);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* APIs that enqueue the request and return ok for acknowledgment.
|
* APIs that enqueue the request and return ok for acknowledgment.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2014-2018 Wind River Systems, Inc.
|
// Copyright (c) 2014-2024 Wind River Systems, Inc.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
@ -250,47 +250,29 @@ bool CFmDbAlarmOperation::get_alarm(CFmDBSession &sess, AlarmFilter &af, fm_db_r
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFmDbAlarmOperation::get_alarms(CFmDBSession &sess,const char *id, fm_db_result_t & alarms) {
|
/** Function similar to 'get_alarm', the only difference is that this could match
|
||||||
|
* several rows, since this is using the LIKE % clause.
|
||||||
|
*/
|
||||||
|
bool CFmDbAlarmOperation::get_alarms_eid_not_strict(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms) {
|
||||||
|
|
||||||
std::string sql;
|
std::string sql;
|
||||||
|
|
||||||
char query[FM_MAX_SQL_STATEMENT_MAX];
|
char query[FM_MAX_SQL_STATEMENT_MAX];
|
||||||
fm_db_result_t res;
|
|
||||||
res.clear();
|
|
||||||
|
|
||||||
sql = FM_DB_SELECT_FROM_TABLE(FM_ALARM_TABLE_NAME);
|
if (strlen(af.entity_instance_id) == 0){
|
||||||
sql += " ";
|
snprintf(query, sizeof(query),"%s = '%s' AND %s = ' '",
|
||||||
|
FM_ALARM_COLUMN_ALARM_ID, af.alarm_id,
|
||||||
sql += " INNER JOIN ";
|
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID);
|
||||||
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
|
|
||||||
sql += " ON ";
|
|
||||||
sql += FM_ALARM_TABLE_NAME;
|
|
||||||
sql += ".";
|
|
||||||
sql += FM_ALARM_COLUMN_ALARM_ID;
|
|
||||||
sql += " = ";
|
|
||||||
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
|
|
||||||
sql += ".";
|
|
||||||
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
|
|
||||||
|
|
||||||
sql += " WHERE ";
|
|
||||||
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
|
|
||||||
sql += ".";
|
|
||||||
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
|
|
||||||
sql += " = '";
|
|
||||||
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
|
|
||||||
sql += "'";
|
|
||||||
|
|
||||||
if (id != NULL){
|
|
||||||
snprintf(query, sizeof(query),"%s like '%s%s'", FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, id,"%");
|
|
||||||
if (NULL!=query) {
|
|
||||||
sql += " AND ";
|
|
||||||
sql += query;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
|
snprintf(query, sizeof(query), "%s = '%s' AND %s LIKE '%s%%'",
|
||||||
if ((sess.query(sql.c_str(), alarms)) != true)
|
FM_ALARM_COLUMN_ALARM_ID, af.alarm_id,
|
||||||
|
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, af.entity_instance_id);
|
||||||
|
}
|
||||||
|
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query, sql);
|
||||||
|
FM_DEBUG_LOG("get_alarm:(%s)\n", sql.c_str());
|
||||||
|
if ((sess.query(sql.c_str(), alarms)) != true){
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,6 +293,71 @@ bool CFmDbAlarmOperation::get_alarms_by_id(CFmDBSession &sess,const char *id, fm
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CFmDbAlarmOperation::get_alarms(CFmDBSession &sess, const char *entity_instance_id, fm_db_result_t &alarms) {
|
||||||
|
std::string sql = CFmDbAlarmOperation::build_base_alarm_query(entity_instance_id);
|
||||||
|
|
||||||
|
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
|
||||||
|
if (!sess.query(sql.c_str(), alarms))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFmDbAlarmOperation::get_alarms_by_id_n_eid(CFmDBSession &sess, const AlarmFilter &af, fm_db_result_t &alarms) {
|
||||||
|
std::string sql = CFmDbAlarmOperation::build_base_alarm_query(af.entity_instance_id);
|
||||||
|
|
||||||
|
if (strlen(af.alarm_id) > 0) {
|
||||||
|
char query[FM_MAX_SQL_STATEMENT_MAX];
|
||||||
|
snprintf(query, sizeof(query), "%s.%s = '%s'", FM_ALARM_TABLE_NAME,
|
||||||
|
FM_ALARM_COLUMN_ALARM_ID, af.alarm_id);
|
||||||
|
sql += " AND ";
|
||||||
|
sql += query;
|
||||||
|
}else{
|
||||||
|
FM_INFO_LOG("Alarm_id not provided \n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
|
||||||
|
if (!sess.query(sql.c_str(), alarms))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CFmDbAlarmOperation::build_base_alarm_query(const char *entity_instance_id) {
|
||||||
|
std::string sql;
|
||||||
|
char query[FM_MAX_SQL_STATEMENT_MAX];
|
||||||
|
|
||||||
|
sql = FM_DB_SELECT_FROM_TABLE(FM_ALARM_TABLE_NAME);
|
||||||
|
sql += " INNER JOIN ";
|
||||||
|
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
|
||||||
|
sql += " ON ";
|
||||||
|
sql += FM_ALARM_TABLE_NAME;
|
||||||
|
sql += ".";
|
||||||
|
sql += FM_ALARM_COLUMN_ALARM_ID;
|
||||||
|
sql += " = ";
|
||||||
|
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
|
||||||
|
sql += ".";
|
||||||
|
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
|
||||||
|
|
||||||
|
sql += " WHERE ";
|
||||||
|
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
|
||||||
|
sql += ".";
|
||||||
|
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
|
||||||
|
sql += " = '";
|
||||||
|
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
|
||||||
|
sql += "'";
|
||||||
|
|
||||||
|
if (entity_instance_id != nullptr) {
|
||||||
|
snprintf(query, sizeof(query), "%s.%s LIKE '%s%s'", FM_ALARM_TABLE_NAME,
|
||||||
|
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, entity_instance_id, "%");
|
||||||
|
sql += " AND ";
|
||||||
|
sql += query;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
bool CFmDbAlarmOperation::get_all_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len ) {
|
bool CFmDbAlarmOperation::get_all_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len ) {
|
||||||
fm_db_result_t res;
|
fm_db_result_t res;
|
||||||
|
|
||||||
|
@ -66,9 +66,16 @@ public:
|
|||||||
|
|
||||||
bool get_alarms_by_id(CFmDBSession &sess, const char *id, fm_db_result_t & alarms);
|
bool get_alarms_by_id(CFmDBSession &sess, const char *id, fm_db_result_t & alarms);
|
||||||
|
|
||||||
|
bool get_alarms_by_id_n_eid(CFmDBSession &sess, const AlarmFilter &af, fm_db_result_t &alarms);
|
||||||
|
|
||||||
|
bool get_alarms_eid_not_strict(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms);
|
||||||
|
|
||||||
bool mask_unmask_alarms(CFmDBSession &sess, SFmAlarmDataT &a, bool mask = true);
|
bool mask_unmask_alarms(CFmDBSession &sess, SFmAlarmDataT &a, bool mask = true);
|
||||||
|
|
||||||
bool add_alarm_history(CFmDBSession &sess, SFmAlarmDataT &a, bool set);
|
bool add_alarm_history(CFmDBSession &sess, SFmAlarmDataT &a, bool set);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::string build_base_alarm_query(const char *entity_instance_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FMDBALARM_H_ */
|
#endif /* FMDBALARM_H_ */
|
||||||
|
@ -436,14 +436,14 @@ bool fm_db_util_build_sql_delete(const char* db_table, AlarmFilter *db_data,
|
|||||||
char sql[FM_MAX_SQL_STATEMENT_MAX];
|
char sql[FM_MAX_SQL_STATEMENT_MAX];
|
||||||
|
|
||||||
if (strlen(db_data->entity_instance_id) == 0){
|
if (strlen(db_data->entity_instance_id) == 0){
|
||||||
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = '%s' AND %s = ' '",
|
snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE %s = '%s' AND %s = ' '",
|
||||||
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
|
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
|
||||||
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID);
|
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = '%s' AND %s = '%s'",
|
snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE %s = '%s' AND %s like '%s%s'",
|
||||||
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
|
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
|
||||||
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, db_data->entity_instance_id);
|
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, db_data->entity_instance_id,"%");
|
||||||
}
|
}
|
||||||
db_cmd.assign(sql);
|
db_cmd.assign(sql);
|
||||||
return true;
|
return true;
|
||||||
@ -456,7 +456,7 @@ bool fm_db_util_build_sql_delete_row(const char* db_table, int id,
|
|||||||
|
|
||||||
char sql[FM_MAX_SQL_STATEMENT_MAX];
|
char sql[FM_MAX_SQL_STATEMENT_MAX];
|
||||||
|
|
||||||
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = %d",
|
snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE %s = %d",
|
||||||
db_table, FM_ALARM_COLUMN_ID, id);
|
db_table, FM_ALARM_COLUMN_ID, id);
|
||||||
db_cmd.assign(sql);
|
db_cmd.assign(sql);
|
||||||
return true;
|
return true;
|
||||||
@ -467,7 +467,7 @@ bool fm_db_util_build_sql_delete_all(const char* db_table, const char *id,
|
|||||||
|
|
||||||
char sql[FM_MAX_SQL_STATEMENT_MAX];
|
char sql[FM_MAX_SQL_STATEMENT_MAX];
|
||||||
|
|
||||||
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s like '%s%s'", db_table,
|
snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE %s like '%s%s'", db_table,
|
||||||
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, id,"%");
|
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, id,"%");
|
||||||
db_cmd.assign(sql);
|
db_cmd.assign(sql);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2014 Wind River Systems, Inc.
|
// Copyright (c) 2024 Wind River Systems, Inc.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
@ -36,6 +36,7 @@ typedef enum {
|
|||||||
EFmGetFaults,
|
EFmGetFaults,
|
||||||
EFmReturnUUID,
|
EFmReturnUUID,
|
||||||
EFmGetFaultsById,
|
EFmGetFaultsById,
|
||||||
|
EFmGetFaultsByIdnEid,
|
||||||
EFmActMax
|
EFmActMax
|
||||||
}EFmMsgActionsT;
|
}EFmMsgActionsT;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2017-2018 Wind River Systems, Inc.
|
// Copyright (c) 2017-2024 Wind River Systems, Inc.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
@ -288,6 +288,97 @@ void get_db_alarms_by_id(CFmDBSession &sess, sFmGetReq &req, void *context){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves faults from the database based on the specified alarm ID and entity instance ID.
|
||||||
|
*
|
||||||
|
* This function queries the database for alarms that match the provided alarm ID
|
||||||
|
* and entity instance ID. The results are then sent back to the client through
|
||||||
|
* the provided socket server processor.
|
||||||
|
*
|
||||||
|
* **Parameters:**
|
||||||
|
* - `sess`: A reference to a `CFmDBSession` object representing the database session.
|
||||||
|
* - `req`: A reference to an `sFmGetReq` structure containing the request data.
|
||||||
|
* - `context`: A pointer to a context object.
|
||||||
|
*
|
||||||
|
* **Process Flow:**
|
||||||
|
* - The function initializes a buffer with the request data and extracts the header and data
|
||||||
|
* sections.
|
||||||
|
* - It casts the data section to an `AlarmFilter` pointer and the context to an
|
||||||
|
* `FmSocketServerProcessor` pointer.
|
||||||
|
* - Database Query
|
||||||
|
* - If alarms are found, it fills a vector with the alarm data.
|
||||||
|
* - Sets the number of alarms found in the buffer and copies the alarm data into the buffer.
|
||||||
|
* - It sends the response back to the client using the `send_response` method of the
|
||||||
|
* `FmSocketServerProcessor`.
|
||||||
|
*
|
||||||
|
* - If no alarms are found, it logs a message and sets the response code to
|
||||||
|
* `FM_ERR_ENTITY_NOT_FOUND`.
|
||||||
|
*
|
||||||
|
* **Returns:**
|
||||||
|
* - The function does not return a value but sends a response back to the client
|
||||||
|
* through the provided socket server processor.
|
||||||
|
*/
|
||||||
|
void get_db_alarms_by_id_n_eid(CFmDBSession &sess, sFmGetReq &req, void *context){
|
||||||
|
|
||||||
|
fm_buff_t buff = req.data;
|
||||||
|
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
|
||||||
|
void * data = &buff[sizeof(SFmMsgHdrT)];
|
||||||
|
AlarmFilter *filter = (AlarmFilter *)data;
|
||||||
|
FmSocketServerProcessor *srv = (FmSocketServerProcessor *)context;
|
||||||
|
CFmDbAlarmOperation op;
|
||||||
|
fm_db_result_t res;
|
||||||
|
std::vector<SFmAlarmDataT> alarmv;
|
||||||
|
|
||||||
|
FM_DEBUG_LOG("handle get_db_alarms_by_id_n_eid:%s\n", filter->alarm_id);
|
||||||
|
|
||||||
|
hdr->msg_rc = FM_ERR_OK;
|
||||||
|
res.clear();
|
||||||
|
if (op.get_alarms_by_id_n_eid(sess, *filter, res) != true){
|
||||||
|
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
|
||||||
|
}else if (res.size() > 0){
|
||||||
|
int ix = 0;
|
||||||
|
int resp_len = res.size();
|
||||||
|
SFmAlarmDataT alarm;
|
||||||
|
alarmv.clear();
|
||||||
|
// Fill the tuple data vector for the response.
|
||||||
|
for ( ; ix < resp_len ; ++ix ) {
|
||||||
|
CFmDbAlarm::convert_to(res[ix],&alarm);
|
||||||
|
alarmv.push_back(alarm);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
FM_DEBUG_LOG("No alarms found for alarm id (%s), "
|
||||||
|
"entity_instance_id (%s)\n",
|
||||||
|
filter->alarm_id, filter->entity_instance_id);
|
||||||
|
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hdr->msg_rc==FM_ERR_OK) && (alarmv.size() > 0)){
|
||||||
|
int found_num_alarms=alarmv.size();
|
||||||
|
FM_DEBUG_LOG("Get faults: found alarms: (%d)", found_num_alarms);
|
||||||
|
|
||||||
|
// (num of alarms found * size of alarm structure) +
|
||||||
|
// space to report number of alarms found.
|
||||||
|
int total_len =(found_num_alarms * sizeof(SFmAlarmDataT)) + sizeof(uint32_t);
|
||||||
|
|
||||||
|
void * buffer = malloc(total_len);
|
||||||
|
if (buffer==NULL) {
|
||||||
|
hdr->msg_rc =FM_ERR_SERVER_NO_MEM;
|
||||||
|
srv->send_response(req.fd,hdr,NULL,0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t *alen = (uint32_t*) buffer;
|
||||||
|
*alen = found_num_alarms;
|
||||||
|
|
||||||
|
SFmAlarmDataT * alarms = (SFmAlarmDataT*) ( ((char*)buffer)+sizeof(uint32_t));
|
||||||
|
|
||||||
|
memcpy(alarms,&(alarmv[0]),alarmv.size() * sizeof(SFmAlarmDataT));
|
||||||
|
srv->send_response(req.fd,hdr,buffer,total_len);
|
||||||
|
free(buffer);
|
||||||
|
} else {
|
||||||
|
srv->send_response(req.fd,hdr,NULL,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fm_handle_job_request(CFmDBSession &sess, sFmJobReq &req){
|
void fm_handle_job_request(CFmDBSession &sess, sFmJobReq &req){
|
||||||
CFmDbAlarmOperation op;
|
CFmDbAlarmOperation op;
|
||||||
CFmEventSuppressionOperation event_suppression_op;
|
CFmEventSuppressionOperation event_suppression_op;
|
||||||
@ -333,6 +424,7 @@ void fm_handle_get_request(CFmDBSession &sess, sFmGetReq &req,
|
|||||||
case EFmGetFault:get_db_alarm(sess,req,context); break;
|
case EFmGetFault:get_db_alarm(sess,req,context); break;
|
||||||
case EFmGetFaults:get_db_alarms(sess,req,context); break;
|
case EFmGetFaults:get_db_alarms(sess,req,context); break;
|
||||||
case EFmGetFaultsById:get_db_alarms_by_id(sess,req,context); break;
|
case EFmGetFaultsById:get_db_alarms_by_id(sess,req,context); break;
|
||||||
|
case EFmGetFaultsByIdnEid:get_db_alarms_by_id_n_eid(sess,req,context); break;
|
||||||
default:
|
default:
|
||||||
FM_ERROR_LOG("Unexpected job request, action:%u\n",hdr->action);
|
FM_ERROR_LOG("Unexpected job request, action:%u\n",hdr->action);
|
||||||
break;
|
break;
|
||||||
@ -471,8 +563,29 @@ void FmSocketServerProcessor::handle_delete_faults(int fd,
|
|||||||
send_response(fd,hdr,NULL,0);
|
send_response(fd,hdr,NULL,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FmSocketServerProcessor::handle_delete_fault(int fd,
|
/**
|
||||||
SFmMsgHdrT *hdr, std::vector<char> &rdata, CFmDBSession &sess) {
|
* Handles the deletion of faults based on the specified filter.
|
||||||
|
*
|
||||||
|
* This function processes the request to delete faults from the database.
|
||||||
|
* It first validates the request, then retrieves matching alarms and deletes
|
||||||
|
* them from the database. If multiple alarms are found, it handles each
|
||||||
|
* alarm separately and enqueues a job for each cleared alarm.
|
||||||
|
*
|
||||||
|
* **Parameters:**
|
||||||
|
* - `fd`: The file descriptor for the client connection.
|
||||||
|
* - `hdr`: A pointer to an `SFmMsgHdrT` structure containing the message header.
|
||||||
|
* - `rdata`: A reference to a vector of characters containing the request data.
|
||||||
|
* - `sess`: A reference to a `CFmDBSession` object representing the database session.
|
||||||
|
*
|
||||||
|
* **Returns:**
|
||||||
|
* - The function does not return a value but sends a response back to the client through
|
||||||
|
* the provided file descriptor.
|
||||||
|
*/
|
||||||
|
void FmSocketServerProcessor::handle_delete_fault(
|
||||||
|
int fd,
|
||||||
|
SFmMsgHdrT *hdr,
|
||||||
|
std::vector<char> &rdata,
|
||||||
|
CFmDBSession &sess) {
|
||||||
|
|
||||||
CFmDbAlarmOperation op;
|
CFmDbAlarmOperation op;
|
||||||
sFmJobReq req;
|
sFmJobReq req;
|
||||||
@ -480,36 +593,54 @@ void FmSocketServerProcessor::handle_delete_fault(int fd,
|
|||||||
SFmAlarmDataT alarm;
|
SFmAlarmDataT alarm;
|
||||||
fm_db_result_t res;
|
fm_db_result_t res;
|
||||||
|
|
||||||
is_request_valid(hdr->msg_size,AlarmFilter);
|
is_request_valid(hdr->msg_size, AlarmFilter);
|
||||||
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
|
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
|
||||||
AlarmFilter *filter = (AlarmFilter *)(data);
|
AlarmFilter *filter = (AlarmFilter *)(data);
|
||||||
hdr->msg_rc = FM_ERR_OK;
|
hdr->msg_rc = FM_ERR_OK;
|
||||||
res.clear();
|
res.clear();
|
||||||
if ((op.get_alarm(sess, *filter, res)) != true){
|
if ((op.get_alarms_eid_not_strict(sess, *filter, res)) != true) {
|
||||||
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
|
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
|
||||||
}else{
|
} else {
|
||||||
if (res.size() > 0){
|
if (res.size() > 0) {
|
||||||
if(op.delete_alarm(sess, *filter) > 0){
|
if (op.delete_alarm(sess, *filter) > 0) {
|
||||||
FM_INFO_LOG("Deleted alarm: (%s) (%s)\n",
|
FM_INFO_LOG("Deleted alarm(s): (%s) (%s)\n",
|
||||||
filter->alarm_id, filter->entity_instance_id);
|
filter->alarm_id, filter->entity_instance_id);
|
||||||
CFmDbAlarm::convert_to(res[0],&alarm);
|
if (res.size() == 1) {
|
||||||
fm_uuid_create(alarm.uuid);
|
// normal workflow, just one alarm match
|
||||||
req.type = FM_ALARM_CLEAR;
|
CFmDbAlarm::convert_to(res[0], &alarm);
|
||||||
req.set = false;
|
fm_uuid_create(alarm.uuid);
|
||||||
req.data = alarm;
|
req.type = FM_ALARM_CLEAR;
|
||||||
enqueue_job(req);
|
req.set = false;
|
||||||
}else{
|
req.data = alarm;
|
||||||
|
enqueue_job(req);
|
||||||
|
} else {
|
||||||
|
// Multiple alarms received
|
||||||
|
for (const auto &entry : res) {
|
||||||
|
SFmAlarmDataT alarm;
|
||||||
|
CFmDbAlarm::data_type entry_copy = entry;
|
||||||
|
CFmDbAlarm::convert_to(entry_copy, &alarm);
|
||||||
|
fm_uuid_create(alarm.uuid);
|
||||||
|
req.type = FM_ALARM_CLEAR;
|
||||||
|
req.set = false;
|
||||||
|
req.data = alarm;
|
||||||
|
enqueue_job(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
|
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
|
||||||
|
FM_INFO_LOG("Deleted alarm failed: (%s) (%s) (%s)\n",
|
||||||
|
filter->alarm_id, filter->entity_instance_id,
|
||||||
|
fm_error_from_int((EFmErrorT)hdr->msg_rc).c_str());
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
|
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
|
||||||
FM_INFO_LOG("Deleted alarm failed: (%s) (%s) (%s)\n",
|
FM_INFO_LOG("Deleted alarm failed: (%s) (%s) (%s)\n",
|
||||||
filter->alarm_id, filter->entity_instance_id,
|
filter->alarm_id, filter->entity_instance_id,
|
||||||
fm_error_from_int((EFmErrorT)hdr->msg_rc).c_str());
|
fm_error_from_int((EFmErrorT)hdr->msg_rc).c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FM_INFO_LOG("Response to delete fault: %u\n", hdr->msg_rc);
|
FM_INFO_LOG("Response to delete fault: %u\n", hdr->msg_rc);
|
||||||
send_response(fd,hdr,NULL,0);
|
send_response(fd, hdr, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FmSocketServerProcessor::handle_get_faults_by_id(int fd,
|
void FmSocketServerProcessor::handle_get_faults_by_id(int fd,
|
||||||
@ -522,6 +653,16 @@ void FmSocketServerProcessor::handle_get_faults_by_id(int fd,
|
|||||||
enqueue_get(req);
|
enqueue_get(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FmSocketServerProcessor::handle_get_faults_by_id_n_eid(int fd,
|
||||||
|
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
|
||||||
|
|
||||||
|
is_request_valid(hdr->msg_size,AlarmFilter);
|
||||||
|
sFmGetReq req;
|
||||||
|
req.fd = fd;
|
||||||
|
req.data = rdata;
|
||||||
|
enqueue_get(req);
|
||||||
|
}
|
||||||
|
|
||||||
void FmSocketServerProcessor::handle_get_faults(int fd,
|
void FmSocketServerProcessor::handle_get_faults(int fd,
|
||||||
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
|
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
|
||||||
|
|
||||||
@ -555,6 +696,7 @@ void FmSocketServerProcessor::handle_socket_data(int fd,
|
|||||||
case EFmGetFault:handle_get_fault(fd,hdr,rdata); break;
|
case EFmGetFault:handle_get_fault(fd,hdr,rdata); break;
|
||||||
case EFmGetFaults:handle_get_faults(fd,hdr,rdata); break;
|
case EFmGetFaults:handle_get_faults(fd,hdr,rdata); break;
|
||||||
case EFmGetFaultsById:handle_get_faults_by_id(fd,hdr,rdata); break;
|
case EFmGetFaultsById:handle_get_faults_by_id(fd,hdr,rdata); break;
|
||||||
|
case EFmGetFaultsByIdnEid:handle_get_faults_by_id_n_eid(fd,hdr,rdata); break;
|
||||||
default:
|
default:
|
||||||
FM_ERROR_LOG("Unexpected client request, action:%u\n",hdr->action);
|
FM_ERROR_LOG("Unexpected client request, action:%u\n",hdr->action);
|
||||||
break;
|
break;
|
||||||
|
@ -31,6 +31,8 @@ protected:
|
|||||||
std::vector<char> &rdata);
|
std::vector<char> &rdata);
|
||||||
virtual void handle_get_faults_by_id(int fd, SFmMsgHdrT *hdr,
|
virtual void handle_get_faults_by_id(int fd, SFmMsgHdrT *hdr,
|
||||||
std::vector<char> &rdata);
|
std::vector<char> &rdata);
|
||||||
|
virtual void handle_get_faults_by_id_n_eid(int fd, SFmMsgHdrT *hdr,
|
||||||
|
std::vector<char> &rdata);
|
||||||
public:
|
public:
|
||||||
void send_response(int fd, SFmMsgHdrT *hdr, void *data, size_t len);
|
void send_response(int fd, SFmMsgHdrT *hdr, void *data, size_t len);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Copyright (c) 2018 Wind River Systems, Inc.
|
// Copyright (c) 2024 Wind River Systems, Inc.
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
@ -13,7 +13,6 @@
|
|||||||
#include "fmAlarmUtils.h"
|
#include "fmAlarmUtils.h"
|
||||||
|
|
||||||
|
|
||||||
static const size_t DEF_MAX_ALARMS (1000);
|
|
||||||
static const size_t MAXSTRINGSIZE (500);
|
static const size_t MAXSTRINGSIZE (500);
|
||||||
static PyObject *logging = NULL;
|
static PyObject *logging = NULL;
|
||||||
|
|
||||||
@ -21,8 +20,8 @@ enum { error, warning, info, debug, max_level };
|
|||||||
|
|
||||||
|
|
||||||
#define LOG_MSG(level,data,...) \
|
#define LOG_MSG(level,data,...) \
|
||||||
log_msg(level, "fm_python_extension: "\
|
log_msg(level, "%s:%d:%s: " data, __FILE__, __LINE__, \
|
||||||
data, ## __VA_ARGS__ )
|
__FUNCTION__, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define ERROR_LOG(data,...) \
|
#define ERROR_LOG(data,...) \
|
||||||
LOG_MSG(error, data, ## __VA_ARGS__)
|
LOG_MSG(error, data, ## __VA_ARGS__)
|
||||||
@ -100,6 +99,65 @@ static PyObject * _fm_set(PyObject * self, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject * _fm_set_list(PyObject * self, PyObject *args) {
|
||||||
|
/* Receives a PyObject expected to be a list of strings
|
||||||
|
containing different alarm information.
|
||||||
|
The function then parses each string into different alarm
|
||||||
|
structures, which are filled and sent to the C++ core. */
|
||||||
|
|
||||||
|
std::string alarm;
|
||||||
|
fm_uuid_t tmp_uuid;
|
||||||
|
PyObject *uuidList = PyList_New(0);
|
||||||
|
EFmErrorT rc = FM_ERR_INVALID_REQ;
|
||||||
|
|
||||||
|
PyObject *listObj = nullptr;
|
||||||
|
if (!PyArg_ParseTuple(args, "O", &listObj)) {
|
||||||
|
ERROR_LOG("Failed to parse args.");
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyList_Check(listObj)) {
|
||||||
|
ERROR_LOG("Expected a list.");
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_ssize_t num_items = PyList_Size(listObj);
|
||||||
|
for (Py_ssize_t i = 0; i < num_items; i++) {
|
||||||
|
PyObject *item = PyList_GetItem(listObj, i);
|
||||||
|
if (!PyUnicode_Check(item)) {
|
||||||
|
ERROR_LOG("List items must be strings.");
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *alm_str = PyUnicode_AsUTF8(item);
|
||||||
|
std::string alarm(alm_str);
|
||||||
|
|
||||||
|
SFmAlarmDataT alm_data;
|
||||||
|
if (!fm_alarm_from_string(alarm, &alm_data)) {
|
||||||
|
ERROR_LOG("Failed to convert string to alarm.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = fm_set_fault(&alm_data, &tmp_uuid);
|
||||||
|
if (rc == FM_ERR_OK) {
|
||||||
|
PyObject *uuidStr = PyUnicode_FromString(tmp_uuid);
|
||||||
|
PyList_Append(uuidList, uuidStr);
|
||||||
|
Py_DECREF(uuidStr);
|
||||||
|
} else if (rc == FM_ERR_NOCONNECT) {
|
||||||
|
WARNING_LOG("Failed to connect to FM manager");
|
||||||
|
} else {
|
||||||
|
ERROR_LOG("Failed to generate an alarm: (%s) (%s)",
|
||||||
|
alm_data.alarm_id, alm_data.entity_instance_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == FM_ERR_OK) {
|
||||||
|
return uuidList;
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject * _fm_get(PyObject * self, PyObject *args) {
|
static PyObject * _fm_get(PyObject * self, PyObject *args) {
|
||||||
|
|
||||||
const char *filter;
|
const char *filter;
|
||||||
@ -237,6 +295,71 @@ static PyObject * _fm_get_by_eid(PyObject * self, PyObject *args, PyObject* kwar
|
|||||||
Py_RETURN_FALSE;
|
Py_RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject * _fm_get_by_id_n_eid(PyObject * self, PyObject *args) {
|
||||||
|
/* Receive a PyObject expected to be a filter containing
|
||||||
|
alarm_id and entity_instance_id. The entity_instance_id
|
||||||
|
does not need to be complete, allowing it to match
|
||||||
|
more than one row.
|
||||||
|
The function parses this object into different alarm
|
||||||
|
strings and fills a filter alarm structure that is
|
||||||
|
sent to the C++ core. */
|
||||||
|
const char *filter;
|
||||||
|
AlarmFilter af;
|
||||||
|
std::string alm_str, filter_str;
|
||||||
|
std::vector< SFmAlarmDataT > lst;
|
||||||
|
unsigned int max= DEF_MAX_ALARMS;
|
||||||
|
EFmErrorT rc;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &filter)) {
|
||||||
|
ERROR_LOG("Failed to parse args.");
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
filter_str.assign(filter);
|
||||||
|
if (!fm_alarm_filter_from_string(filter_str, &af)) {
|
||||||
|
ERROR_LOG("Invalid alarm filter: (%s)",
|
||||||
|
filter_str.c_str());
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
lst.resize(max);
|
||||||
|
} catch(...) {
|
||||||
|
ERROR_LOG("Failed to allocate memory.");
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int max_alarms_to_get = max;
|
||||||
|
rc = fm_get_faults_by_id_n_eid(&af, &(lst[0]), &max_alarms_to_get);
|
||||||
|
if (rc == FM_ERR_OK) {
|
||||||
|
PyObject *__lst = PyList_New(0);
|
||||||
|
for ( size_t ix = 0; ix < max_alarms_to_get; ++ix ) {
|
||||||
|
std::string s;
|
||||||
|
fm_alarm_to_string(&lst[ix], s);
|
||||||
|
if (s.size() > 0) {
|
||||||
|
if (PyList_Append(__lst,PyUnicode_FromString(s.c_str())) != 0) {
|
||||||
|
ERROR_LOG("Failed to append alarm to the list");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* python will garbage collect if the reference count is correct
|
||||||
|
(it should be 1 at this point) */
|
||||||
|
return __lst;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == FM_ERR_ENTITY_NOT_FOUND) {
|
||||||
|
DEBUG_LOG("Alarm id (%s), Entity id:(%s) not found",
|
||||||
|
af.alarm_id, af.entity_instance_id);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
} else if (rc == FM_ERR_NOCONNECT) {
|
||||||
|
WARNING_LOG("Failed to connect to FM manager");
|
||||||
|
} else {
|
||||||
|
ERROR_LOG("Failed to get alarm list for entity id (%s), error code: (%d)",
|
||||||
|
af.entity_instance_id, rc);
|
||||||
|
}
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject * _fm_clear(PyObject * self, PyObject *args) {
|
static PyObject * _fm_clear(PyObject * self, PyObject *args) {
|
||||||
|
|
||||||
const char *filter;
|
const char *filter;
|
||||||
@ -312,6 +435,10 @@ static PyMethodDef _methods [] = {
|
|||||||
"Get alarms by alarm id" },
|
"Get alarms by alarm id" },
|
||||||
{ "get_by_eid", (PyCFunction)_fm_get_by_eid, METH_VARARGS | METH_KEYWORDS,
|
{ "get_by_eid", (PyCFunction)_fm_get_by_eid, METH_VARARGS | METH_KEYWORDS,
|
||||||
"Get alarms by entity instance id" },
|
"Get alarms by entity instance id" },
|
||||||
|
{ "get_by_id_n_eid", _fm_get_by_id_n_eid, METH_VARARGS,
|
||||||
|
"Get list of alarms by filter" },
|
||||||
|
{ "set_fault_list", _fm_set_list, METH_VARARGS,
|
||||||
|
"Set alarm list" },
|
||||||
{ NULL, NULL, 0, NULL }
|
{ NULL, NULL, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user