mirror of
https://github.com/emqx/neuron.git
synced 2026-10-17 04:40:42 +08:00
Merge pull request #1670 from hxy7yx/main-3
improve: core/adapter log level
This commit is contained in:
@@ -36,7 +36,7 @@ extern "C" {
|
||||
typedef struct {
|
||||
neu_node_running_state_e running;
|
||||
neu_node_link_state_e link;
|
||||
char log_level[NEU_LOG_LEVEL_LEN];
|
||||
int log_level;
|
||||
} neu_node_state_t;
|
||||
|
||||
typedef enum neu_reqresp_type {
|
||||
@@ -624,7 +624,9 @@ typedef struct neu_req_get_node_state {
|
||||
typedef struct neu_resp_get_node_state {
|
||||
neu_node_state_t state;
|
||||
uint16_t rtt; // round trip time in milliseconds
|
||||
char core_level[NEU_LOG_LEVEL_LEN];
|
||||
int core_level;
|
||||
uint16_t sub_group_count;
|
||||
bool is_driver;
|
||||
} neu_resp_get_node_state_t;
|
||||
|
||||
typedef struct neu_req_get_nodes_state {
|
||||
@@ -634,6 +636,8 @@ typedef struct {
|
||||
char node[NEU_NODE_NAME_LEN];
|
||||
neu_node_state_t state;
|
||||
uint16_t rtt; // round trip time in milliseconds
|
||||
uint16_t sub_group_count;
|
||||
bool is_driver;
|
||||
} neu_nodes_state_t;
|
||||
|
||||
inline static UT_icd neu_nodes_state_t_icd()
|
||||
@@ -644,7 +648,7 @@ inline static UT_icd neu_nodes_state_t_icd()
|
||||
}
|
||||
typedef struct {
|
||||
UT_array *states; // array of neu_nodes_state_t
|
||||
char core_level[NEU_LOG_LEVEL_LEN];
|
||||
int core_level;
|
||||
} neu_resp_get_nodes_state_t, neu_reqresp_nodes_state_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -1086,7 +1090,7 @@ typedef struct {
|
||||
|
||||
typedef struct neu_req_update_log_level {
|
||||
char node[NEU_NODE_NAME_LEN];
|
||||
char log_level[NEU_LOG_LEVEL_LEN];
|
||||
int log_level;
|
||||
bool core;
|
||||
} neu_req_update_log_level_t;
|
||||
|
||||
|
||||
@@ -25,8 +25,32 @@ config_ **/
|
||||
|
||||
#include "utils/zlog.h"
|
||||
|
||||
#include "define.h"
|
||||
|
||||
extern zlog_category_t *neuron;
|
||||
|
||||
inline static const char *log_level_to_str(int level)
|
||||
{
|
||||
switch (level) {
|
||||
case ZLOG_LEVEL_FATAL:
|
||||
return NEU_LOG_LEVEL_FATAL;
|
||||
case ZLOG_LEVEL_ERROR:
|
||||
return NEU_LOG_LEVEL_ERROR;
|
||||
case ZLOG_LEVEL_WARN:
|
||||
return NEU_LOG_LEVEL_WARN;
|
||||
case ZLOG_LEVEL_NOTICE:
|
||||
return NEU_LOG_LEVEL_NOTICE;
|
||||
case ZLOG_LEVEL_INFO:
|
||||
return NEU_LOG_LEVEL_INFO;
|
||||
case ZLOG_LEVEL_DEBUG:
|
||||
return NEU_LOG_LEVEL_DEBUG;
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
#define nlog_level_change(level) zlog_level_switch(neuron, level)
|
||||
|
||||
#define nlog_fatal(...) \
|
||||
zlog(neuron, __FILE__, sizeof(__FILE__) - 1, __func__, \
|
||||
sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_FATAL, __VA_ARGS__)
|
||||
|
||||
@@ -330,11 +330,13 @@ void handle_get_node_state_resp(nng_aio *aio, neu_resp_get_node_state_t *state)
|
||||
neu_json_get_node_state_resp_t res = { 0 };
|
||||
char * result = NULL;
|
||||
|
||||
res.link = state->state.link;
|
||||
res.running = state->state.running;
|
||||
res.rtt = state->rtt;
|
||||
res.log_level = state->state.log_level;
|
||||
strcpy(res.core_level, state->core_level);
|
||||
res.link = state->state.link;
|
||||
res.running = state->state.running;
|
||||
res.rtt = state->rtt;
|
||||
res.sub_group_count = state->sub_group_count;
|
||||
res.is_driver = state->is_driver;
|
||||
res.log_level = (char *) log_level_to_str(state->state.log_level);
|
||||
res.core_level = (char *) log_level_to_str(state->core_level);
|
||||
|
||||
neu_json_encode_by_fn(&res, neu_json_encode_get_node_state_resp, &result);
|
||||
|
||||
@@ -359,10 +361,13 @@ void handle_get_nodes_state_resp(nng_aio * aio,
|
||||
states_res.nodes[index].running = state->state.running;
|
||||
states_res.nodes[index].link = state->state.link;
|
||||
states_res.nodes[index].rtt = state->rtt;
|
||||
states_res.nodes[index].log_level = state->state.log_level;
|
||||
states_res.nodes[index].sub_group_count = state->sub_group_count;
|
||||
states_res.nodes[index].is_driver = state->is_driver;
|
||||
states_res.nodes[index].log_level =
|
||||
(char *) log_level_to_str(state->state.log_level);
|
||||
}
|
||||
|
||||
strcpy(states_res.core_level, states->core_level);
|
||||
states_res.core_level = (char *) log_level_to_str(states->core_level);
|
||||
|
||||
neu_json_encode_by_fn(&states_res, neu_json_encode_get_nodes_state_resp,
|
||||
&result);
|
||||
|
||||
@@ -113,78 +113,48 @@ void handle_log_level(nng_aio *aio)
|
||||
NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT(
|
||||
aio, neu_json_update_log_level_req_t,
|
||||
neu_json_decode_update_log_level_req, {
|
||||
int ret = 0;
|
||||
neu_reqresp_head_t header = { 0 };
|
||||
neu_req_update_log_level_t cmd = { 0 };
|
||||
int log_level;
|
||||
neu_reqresp_head_t header = { 0 };
|
||||
neu_req_update_log_level_t cmd = { 0 };
|
||||
int log_level = -1;
|
||||
|
||||
if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_DEBUG)) {
|
||||
log_level = ZLOG_LEVEL_DEBUG;
|
||||
strcpy(cmd.log_level, NEU_LOG_LEVEL_DEBUG);
|
||||
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_INFO)) {
|
||||
log_level = ZLOG_LEVEL_INFO;
|
||||
strcpy(cmd.log_level, NEU_LOG_LEVEL_INFO);
|
||||
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_NOTICE)) {
|
||||
log_level = ZLOG_LEVEL_NOTICE;
|
||||
strcpy(cmd.log_level, NEU_LOG_LEVEL_NOTICE);
|
||||
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_WARN)) {
|
||||
log_level = ZLOG_LEVEL_WARN;
|
||||
strcpy(cmd.log_level, NEU_LOG_LEVEL_WARN);
|
||||
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_ERROR)) {
|
||||
log_level = ZLOG_LEVEL_ERROR;
|
||||
strcpy(cmd.log_level, NEU_LOG_LEVEL_ERROR);
|
||||
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_FATAL)) {
|
||||
log_level = ZLOG_LEVEL_FATAL;
|
||||
strcpy(cmd.log_level, NEU_LOG_LEVEL_FATAL);
|
||||
} else {
|
||||
strcpy(cmd.log_level, "unknow");
|
||||
nlog_error(
|
||||
"Failed to modify log_level of the node, node_name:%s, ",
|
||||
req->node_name);
|
||||
nlog_error("Failed to modify log_level of the node, "
|
||||
"node_name:%s, log_level: %s",
|
||||
req->node_name, req->log_level);
|
||||
}
|
||||
|
||||
if (log_level == -1) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
goto end;
|
||||
}
|
||||
if (req->core) {
|
||||
zlog_category_t *neuron = zlog_get_category("neuron");
|
||||
ret = zlog_level_switch(neuron, log_level);
|
||||
} else {
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_UPDATE_LOG_LEVEL;
|
||||
cmd.core = req->core;
|
||||
cmd.log_level = log_level;
|
||||
if (req->node_name != NULL) {
|
||||
strcpy(cmd.node, req->node_name);
|
||||
}
|
||||
|
||||
int ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
nlog_error(
|
||||
"Failed to modify log_level of the core, ret: %d", ret);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
});
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (req->node_name) {
|
||||
zlog_category_t *ct = zlog_get_category(req->node_name);
|
||||
strcpy(cmd.node, req->node_name);
|
||||
ret = zlog_level_switch(ct, log_level);
|
||||
if (ret != 0) {
|
||||
nlog_error(
|
||||
"Failed to modify log_level of the node, node_name:%s, "
|
||||
"ret: %d,",
|
||||
req->node_name, ret);
|
||||
NEU_JSON_RESPONSE_ERROR(0, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_UPDATE_LOG_LEVEL;
|
||||
cmd.core = req->core;
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
});
|
||||
}
|
||||
end:;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+10
-6
@@ -147,6 +147,7 @@ neu_adapter_t *neu_adapter_create(neu_adapter_info_t *info, bool load)
|
||||
adapter->module = info->module;
|
||||
adapter->timestamp_lev = 0;
|
||||
adapter->trans_data_port = 0;
|
||||
adapter->log_level = ZLOG_LEVEL_NOTICE;
|
||||
|
||||
struct sockaddr_in remote = {
|
||||
.sin_family = AF_INET,
|
||||
@@ -487,9 +488,7 @@ static int adapter_command(neu_adapter_t *adapter, neu_reqresp_head_t header,
|
||||
}
|
||||
case NEU_REQ_UPDATE_LOG_LEVEL: {
|
||||
neu_req_update_log_level_t *cmd = (neu_req_update_log_level_t *) data;
|
||||
if (cmd->node != NULL) {
|
||||
strcpy(pheader->receiver, cmd->node);
|
||||
}
|
||||
strcpy(pheader->receiver, cmd->node);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1234,7 +1233,12 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_UPDATE_LOG_LEVEL: {
|
||||
neu_req_update_log_level_t *cmd =
|
||||
(neu_req_update_log_level_t *) &header[1];
|
||||
neu_resp_error_t error = { 0 };
|
||||
adapter->log_level = cmd->log_level;
|
||||
zlog_level_switch(neu_plugin_to_plugin_common(adapter->plugin)->log,
|
||||
cmd->log_level);
|
||||
|
||||
struct timeval tv = { 0 };
|
||||
gettimeofday(&tv, NULL);
|
||||
@@ -1426,9 +1430,9 @@ neu_node_state_t neu_adapter_get_state(neu_adapter_t *adapter)
|
||||
neu_node_state_t state = { 0 };
|
||||
neu_plugin_common_t *common = neu_plugin_to_plugin_common(adapter->plugin);
|
||||
|
||||
state.link = common->link_state;
|
||||
state.running = adapter->state;
|
||||
strcpy(state.log_level, common->log_level);
|
||||
state.link = common->link_state;
|
||||
state.running = adapter->state;
|
||||
state.log_level = adapter->log_level;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ struct neu_adapter {
|
||||
|
||||
neu_node_running_state_e state;
|
||||
|
||||
char log_level[NEU_LOG_LEVEL_LEN];
|
||||
|
||||
adapter_callbacks_t cb_funs;
|
||||
|
||||
void * handle;
|
||||
@@ -59,6 +57,7 @@ struct neu_adapter {
|
||||
|
||||
// metrics
|
||||
neu_node_metrics_t *metrics;
|
||||
int log_level;
|
||||
};
|
||||
|
||||
typedef void (*adapter_handler)(neu_adapter_t * adapter,
|
||||
|
||||
@@ -31,7 +31,6 @@ void neu_plugin_common_init(neu_plugin_common_t *common)
|
||||
{
|
||||
common->magic = NEU_PLUGIN_MAGIC_NUMBER;
|
||||
common->link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
|
||||
strcpy(common->log_level, NEU_LOG_LEVEL_NOTICE);
|
||||
}
|
||||
|
||||
bool neu_plugin_common_check(neu_plugin_t *plugin)
|
||||
|
||||
+45
-62
@@ -101,6 +101,7 @@ neu_manager_t *neu_manager_create()
|
||||
manager->node_manager = neu_node_manager_create();
|
||||
manager->subscribe_manager = neu_subscribe_manager_create();
|
||||
manager->template_manager = neu_template_manager_create();
|
||||
manager->log_level = ZLOG_LEVEL_NOTICE;
|
||||
|
||||
manager->server_fd =
|
||||
socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
|
||||
@@ -1160,12 +1161,14 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_REQ_GET_NODES_STATE: {
|
||||
neu_resp_get_nodes_state_t resp = { 0 };
|
||||
UT_array *states = neu_node_manager_get_state(manager->node_manager);
|
||||
|
||||
neu_adapter_t *adapter_core =
|
||||
neu_node_manager_find(manager->node_manager, "default-dashboard");
|
||||
strcpy(resp.core_level,
|
||||
neu_plugin_to_plugin_common(adapter_core->plugin)->log_level);
|
||||
resp.states = utarray_clone(states);
|
||||
neu_nodes_state_t *p_state = NULL;
|
||||
while (
|
||||
(p_state = (neu_nodes_state_t *) utarray_next(states, p_state))) {
|
||||
p_state->sub_group_count = neu_subscribe_manager_group_count(
|
||||
manager->subscribe_manager, p_state->node);
|
||||
}
|
||||
resp.states = utarray_clone(states);
|
||||
resp.core_level = manager->log_level;
|
||||
|
||||
strcpy(header->receiver, header->sender);
|
||||
strcpy(header->sender, "manager");
|
||||
@@ -1219,13 +1222,6 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
neu_msg_exchange(header);
|
||||
reply(manager, header, &e);
|
||||
} else {
|
||||
neu_resp_get_node_state_t *resp =
|
||||
(neu_resp_get_node_state_t *) &header[1];
|
||||
neu_adapter_t *adapter_core = neu_node_manager_find(
|
||||
manager->node_manager, "default-dashboard");
|
||||
strcpy(
|
||||
resp->core_level,
|
||||
neu_plugin_to_plugin_common(adapter_core->plugin)->log_level);
|
||||
forward_msg(manager, header, header->receiver);
|
||||
}
|
||||
|
||||
@@ -1427,12 +1423,26 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_RESP_GET_NDRIVER_TAGS:
|
||||
case NEU_RESP_GET_GROUP:
|
||||
case NEU_RESP_GET_NODE_SETTING:
|
||||
case NEU_RESP_GET_NODE_STATE:
|
||||
case NEU_RESP_ERROR:
|
||||
case NEU_RESP_READ_GROUP:
|
||||
forward_msg(manager, header, header->receiver);
|
||||
break;
|
||||
|
||||
case NEU_RESP_GET_NODE_STATE: {
|
||||
neu_resp_get_node_state_t *resp =
|
||||
(neu_resp_get_node_state_t *) &header[1];
|
||||
|
||||
neu_adapter_t *adapter_node =
|
||||
neu_node_manager_find(manager->node_manager, header->sender);
|
||||
resp->sub_group_count = neu_subscribe_manager_group_count(
|
||||
manager->subscribe_manager, header->sender);
|
||||
resp->is_driver =
|
||||
(adapter_node->module->type == NEU_NA_TYPE_DRIVER) ? true : false;
|
||||
resp->core_level = manager->log_level;
|
||||
|
||||
forward_msg(manager, header, header->receiver);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_NDRIVER_MAP: {
|
||||
neu_req_ndriver_map_t *cmd = (neu_req_ndriver_map_t *) &header[1];
|
||||
neu_resp_error_t error = { 0 };
|
||||
@@ -1514,58 +1524,31 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
(neu_req_update_log_level_t *) &header[1];
|
||||
|
||||
if (cmd->core) {
|
||||
if (strcmp(header->receiver, "") == 0) {
|
||||
neu_adapter_t *adapter_core = neu_node_manager_find(
|
||||
manager->node_manager, "default-dashboard");
|
||||
strcpy(neu_plugin_to_plugin_common(adapter_core->plugin)
|
||||
->log_level,
|
||||
cmd->log_level);
|
||||
neu_resp_error_t error = { 0 };
|
||||
neu_msg_exchange(header);
|
||||
header->type = NEU_RESP_ERROR;
|
||||
reply(manager, header, &error);
|
||||
} else {
|
||||
if (neu_node_manager_find(manager->node_manager,
|
||||
header->receiver) == NULL) {
|
||||
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
|
||||
header->type = NEU_RESP_ERROR;
|
||||
neu_msg_exchange(header);
|
||||
reply(manager, header, &e);
|
||||
} else {
|
||||
neu_adapter_t *adapter_core = neu_node_manager_find(
|
||||
manager->node_manager, "default-dashboard");
|
||||
strcpy(neu_plugin_to_plugin_common(adapter_core->plugin)
|
||||
->log_level,
|
||||
cmd->log_level);
|
||||
neu_adapter_t *adapter_log = neu_node_manager_find(
|
||||
manager->node_manager, header->receiver);
|
||||
strcpy(neu_plugin_to_plugin_common(adapter_log->plugin)
|
||||
->log_level,
|
||||
cmd->log_level);
|
||||
forward_msg(manager, header, header->receiver);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strcmp(header->receiver, "") == 0) {
|
||||
neu_resp_error_t e = { .error = NEU_ERR_PARAM_IS_WRONG };
|
||||
manager->log_level = cmd->log_level;
|
||||
nlog_level_change(manager->log_level);
|
||||
}
|
||||
|
||||
if (strlen(cmd->node) > 0) {
|
||||
if (neu_node_manager_find(manager->node_manager,
|
||||
header->receiver) == NULL) {
|
||||
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
|
||||
header->type = NEU_RESP_ERROR;
|
||||
neu_msg_exchange(header);
|
||||
reply(manager, header, &e);
|
||||
} else {
|
||||
if (neu_node_manager_find(manager->node_manager,
|
||||
header->receiver) == NULL) {
|
||||
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
|
||||
header->type = NEU_RESP_ERROR;
|
||||
neu_msg_exchange(header);
|
||||
reply(manager, header, &e);
|
||||
} else {
|
||||
neu_adapter_t *adapter_log = neu_node_manager_find(
|
||||
manager->node_manager, header->receiver);
|
||||
strcpy(neu_plugin_to_plugin_common(adapter_log->plugin)
|
||||
->log_level,
|
||||
cmd->log_level);
|
||||
forward_msg(manager, header, header->receiver);
|
||||
}
|
||||
forward_msg(manager, header, header->receiver);
|
||||
}
|
||||
} else {
|
||||
if (cmd->core) {
|
||||
neu_resp_error_t e = { .error = NEU_ERR_SUCCESS };
|
||||
header->type = NEU_RESP_ERROR;
|
||||
neu_msg_exchange(header);
|
||||
reply(manager, header, &e);
|
||||
} else {
|
||||
neu_resp_error_t e = { .error = NEU_ERR_PARAM_IS_WRONG };
|
||||
header->type = NEU_RESP_ERROR;
|
||||
neu_msg_exchange(header);
|
||||
reply(manager, header, &e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,10 @@
|
||||
#include "template_manager.h"
|
||||
|
||||
typedef struct neu_manager {
|
||||
int server_fd;
|
||||
uint8_t buf[NEU_MSG_MAX_SIZE];
|
||||
uint8_t recv_buf[NEU_MSG_MAX_SIZE];
|
||||
int server_fd;
|
||||
uint8_t buf[NEU_MSG_MAX_SIZE];
|
||||
uint8_t recv_buf[NEU_MSG_MAX_SIZE];
|
||||
|
||||
neu_events_t * events;
|
||||
neu_event_io_t *loop;
|
||||
|
||||
@@ -43,6 +44,8 @@ typedef struct neu_manager {
|
||||
neu_event_timer_t *timer_timestamp;
|
||||
|
||||
int64_t timestamp_lev_manager;
|
||||
|
||||
int log_level;
|
||||
} neu_manager_t;
|
||||
|
||||
int neu_manager_add_plugin(neu_manager_t *manager, const char *library);
|
||||
|
||||
@@ -414,8 +414,10 @@ UT_array *neu_node_manager_get_state(neu_node_manager_t *mgr)
|
||||
state.state.running = el->adapter->state;
|
||||
state.state.link =
|
||||
neu_plugin_to_plugin_common(el->adapter->plugin)->link_state;
|
||||
strcpy(state.state.log_level,
|
||||
neu_plugin_to_plugin_common(el->adapter->plugin)->log_level);
|
||||
state.state.log_level = el->adapter->log_level;
|
||||
state.is_driver = (el->adapter->module->type == NEU_NA_TYPE_DRIVER)
|
||||
? true
|
||||
: false;
|
||||
neu_metric_entry_t *e = NULL;
|
||||
if (NULL != el->adapter->metrics) {
|
||||
HASH_FIND_STR(el->adapter->metrics->entries,
|
||||
|
||||
@@ -132,6 +132,25 @@ UT_array *neu_subscribe_manager_get(neu_subscribe_mgr_t *mgr, const char *app)
|
||||
return groups;
|
||||
}
|
||||
|
||||
size_t neu_subscribe_manager_group_count(const neu_subscribe_mgr_t *mgr,
|
||||
const char * app)
|
||||
{
|
||||
size_t group_count = 0;
|
||||
sub_elem_t *current_element, *tmp;
|
||||
|
||||
HASH_ITER(hh, mgr->ss, current_element, tmp)
|
||||
{
|
||||
utarray_foreach(current_element->apps, neu_app_subscribe_t *, sub_app)
|
||||
{
|
||||
if (strcmp(sub_app->app_name, app) == 0) {
|
||||
group_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return group_count;
|
||||
}
|
||||
|
||||
UT_array *neu_subscribe_manager_get_ndriver_maps(neu_subscribe_mgr_t *mgr,
|
||||
const char * ndriver)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,8 @@ UT_array *neu_subscribe_manager_find(neu_subscribe_mgr_t *mgr,
|
||||
UT_array *neu_subscribe_manager_find_by_driver(neu_subscribe_mgr_t *mgr,
|
||||
const char * driver);
|
||||
UT_array *neu_subscribe_manager_get(neu_subscribe_mgr_t *mgr, const char *app);
|
||||
size_t neu_subscribe_manager_group_count(const neu_subscribe_mgr_t *mgr,
|
||||
const char * app);
|
||||
UT_array *neu_subscribe_manager_get_ndriver_maps(neu_subscribe_mgr_t *mgr,
|
||||
const char * ndriver);
|
||||
void neu_subscribe_manager_unsub_all(neu_subscribe_mgr_t *mgr, const char *app);
|
||||
|
||||
@@ -169,6 +169,7 @@ int neu_json_encode_get_node_state_resp(void *json_object, void *param)
|
||||
int ret = 0;
|
||||
neu_json_get_node_state_resp_t *resp =
|
||||
(neu_json_get_node_state_resp_t *) param;
|
||||
int array_size = resp->is_driver ? 5 : 6;
|
||||
|
||||
neu_json_elem_t resp_elems[] = { {
|
||||
.name = "running",
|
||||
@@ -194,9 +195,14 @@ int neu_json_encode_get_node_state_resp(void *json_object, void *param)
|
||||
.name = "neuron_core",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = resp->core_level,
|
||||
},
|
||||
{
|
||||
.name = "sub_group_count",
|
||||
.t = NEU_JSON_INT,
|
||||
.v.val_int = resp->sub_group_count,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, resp_elems,
|
||||
NEU_JSON_ELEM_SIZE(resp_elems));
|
||||
|
||||
ret = neu_json_encode_field(json_object, resp_elems, array_size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -210,6 +216,7 @@ int neu_json_encode_get_nodes_state_resp(void *json_object, void *param)
|
||||
void * node_array = neu_json_array();
|
||||
neu_json_get_nodes_state_t *p_node = resp->nodes;
|
||||
for (int i = 0; i < resp->n_node; i++) {
|
||||
int array_size = p_node->is_driver ? 5 : 6;
|
||||
neu_json_elem_t node_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
@@ -234,9 +241,15 @@ int neu_json_encode_get_nodes_state_resp(void *json_object, void *param)
|
||||
.name = "log_level",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = p_node->log_level,
|
||||
},
|
||||
{
|
||||
.name = "sub_group_count",
|
||||
.t = NEU_JSON_INT,
|
||||
.v.val_int =
|
||||
p_node->sub_group_count,
|
||||
} };
|
||||
node_array = neu_json_encode_array(node_array, node_elems,
|
||||
NEU_JSON_ELEM_SIZE(node_elems));
|
||||
|
||||
node_array = neu_json_encode_array(node_array, node_elems, array_size);
|
||||
p_node++;
|
||||
}
|
||||
|
||||
|
||||
+15
-11
@@ -50,27 +50,31 @@ int neu_json_decode_del_node_req(char *buf, neu_json_del_node_req_t **result);
|
||||
void neu_json_decode_del_node_req_free(neu_json_del_node_req_t *req);
|
||||
|
||||
typedef struct {
|
||||
int64_t running;
|
||||
int64_t link;
|
||||
int64_t rtt;
|
||||
char * log_level;
|
||||
char core_level[NEU_LOG_LEVEL_LEN];
|
||||
int64_t running;
|
||||
int64_t link;
|
||||
int64_t rtt;
|
||||
uint16_t sub_group_count;
|
||||
bool is_driver;
|
||||
char * log_level;
|
||||
char * core_level;
|
||||
} neu_json_get_node_state_resp_t;
|
||||
|
||||
int neu_json_encode_get_node_state_resp(void *json_object, void *param);
|
||||
|
||||
typedef struct {
|
||||
char * name;
|
||||
int64_t running;
|
||||
int64_t link;
|
||||
int64_t rtt;
|
||||
char * log_level;
|
||||
char * name;
|
||||
int64_t running;
|
||||
int64_t link;
|
||||
int64_t rtt;
|
||||
uint16_t sub_group_count;
|
||||
bool is_driver;
|
||||
char * log_level;
|
||||
} neu_json_get_nodes_state_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t n_node;
|
||||
neu_json_get_nodes_state_t *nodes;
|
||||
char core_level[NEU_LOG_LEVEL_LEN];
|
||||
char * core_level;
|
||||
} neu_json_get_nodes_state_resp_t;
|
||||
|
||||
int neu_json_encode_get_nodes_state_resp(void *json_object, void *param);
|
||||
|
||||
@@ -470,7 +470,6 @@ int neu_json_decode_gtag_json(void *json_obj, neu_json_gtag_t *gtag_p)
|
||||
goto decode_exit;
|
||||
|
||||
decode_fail:
|
||||
free(gtag_p);
|
||||
free(gtag_elems[0].v.val_str);
|
||||
return -1;
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import sys
|
||||
|
||||
sys.path.append("tests/ft")
|
||||
@@ -0,0 +1,97 @@
|
||||
import neuron.api as api
|
||||
import neuron.error as error
|
||||
import neuron.config as config
|
||||
from neuron.common import *
|
||||
|
||||
hold_int16 = [{"name": "hold_int16", "address": "1!400001",
|
||||
"attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}]
|
||||
|
||||
class TestDriver:
|
||||
|
||||
@description(given="running neuron", when="add driver node", then="add success")
|
||||
@pytest.mark.parametrize('node,plugin', [('modbus-tcp-1', config.PLUGIN_MODBUS_TCP)])
|
||||
def test_create_driver_node(self, node, plugin):
|
||||
response = api.add_node(node=node,
|
||||
plugin=plugin)
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
@description(given="running neuron", when="add app node", then="add success")
|
||||
@pytest.mark.parametrize('node,plugin', [('mqtt-1', config.PLUGIN_MQTT)])
|
||||
def test_create_app_node(self, node, plugin):
|
||||
response = api.add_node(node=node,
|
||||
plugin=plugin)
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
@description(given="modbus tcp node", when="setting modbus tcp node and groups/tags", then="setting success")
|
||||
def test_modbus_tcp_setting(self):
|
||||
response = api.modbus_tcp_node_setting(node='modbus-tcp-1', port=502)
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.add_group(node='modbus-tcp-1', group="group-1")
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.add_group(node='modbus-tcp-1', group="group-2")
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.add_group(node='modbus-tcp-1', group="group-3")
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.add_tags(node='modbus-tcp-1', group="group-1", tags=hold_int16)
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.add_tags(node='modbus-tcp-1', group="group-2", tags=hold_int16)
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.add_tags(node='modbus-tcp-1', group="group-3", tags=hold_int16)
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
@description(given="mqtt node", when="setting mqtt node and subscribe modbus group", then="setting&subscribe success")
|
||||
def test_mqtt_setting(self):
|
||||
response = api.mqtt_node_setting(node='mqtt-1')
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.subscribe_groups(app='mqtt-1', groups=[{"driver": "modbus-tcp-1", "group": "group-1"},
|
||||
{"driver": "modbus-tcp-1", "group": "group-2"},
|
||||
{"driver": "modbus-tcp-1", "group": "group-3"}])
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
@description(given="mqtt node", when="subscribe/unsubscribe modbus group", then="return correct sub_group_count in node state")
|
||||
def test_mqtt_sub_group_count(self):
|
||||
response = api.get_nodes_state(node='mqtt-1')
|
||||
assert 200 == response.status_code
|
||||
assert 3 == response.json()['sub_group_count']
|
||||
|
||||
response = api.unsubscribe_group(app='mqtt-1', driver='modbus-tcp-1', group='group-1')
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.unsubscribe_group(app='mqtt-1', driver='modbus-tcp-1', group='group-2')
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.unsubscribe_group(app='mqtt-1', driver='modbus-tcp-1', group='group-3')
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.get_nodes_state(node='mqtt-1')
|
||||
assert 200 == response.status_code
|
||||
assert 0 == response.json()['sub_group_count']
|
||||
|
||||
response = api.subscribe_group(app='mqtt-1', driver='modbus-tcp-1', group='group-1')
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
response = api.get_nodes_state(node='mqtt-1')
|
||||
assert 200 == response.status_code
|
||||
assert 1 == response.json()['sub_group_count']
|
||||
+13
-1
@@ -157,7 +157,6 @@ def read_tag(node, group, tag, sync=False):
|
||||
finally:
|
||||
return x[0]['value']
|
||||
|
||||
|
||||
def read_tag_error(node, group, tag, sync=False):
|
||||
response = read_tags(node, group, sync)
|
||||
assert 200 == response.status_code
|
||||
@@ -282,6 +281,14 @@ def del_template_tags(tmpl, group, tags):
|
||||
def get_template_tags(tmpl, group, name):
|
||||
return requests.get(url=config.BASE_URL + "/api/v2/template/tag", headers={"Authorization": config.default_jwt}, params={"template": tmpl, "group": group, "name": name})
|
||||
|
||||
def subscribe_group(app, driver, group):
|
||||
return requests.post(url=config.BASE_URL + "/api/v2/subscribe", headers={"Authorization": config.default_jwt}, json={"app": app, "driver": driver, "group": group})
|
||||
|
||||
def subscribe_groups(app, groups):
|
||||
return requests.post(url=config.BASE_URL + "/api/v2/subscribes", headers={"Authorization": config.default_jwt}, json={"app": app, "groups": groups})
|
||||
|
||||
def unsubscribe_group(app, driver, group):
|
||||
return requests.delete(url=config.BASE_URL + "/api/v2/subscribe", headers={"Authorization": config.default_jwt}, json={"app": app, "driver": driver, "group": group})
|
||||
|
||||
def get_metrics(category="global", node=""):
|
||||
return requests.get(url=config.BASE_URL + "/api/v2/metrics?category=" + category + "&node=" + node, headers={"Authorization": config.default_jwt})
|
||||
@@ -299,3 +306,8 @@ def modbus_rtu_node_setting(node, port, connection_mode=0, transport_mode=0, int
|
||||
"interval": interval, "host": host, "port": port, "timeout": timeout,
|
||||
"max_retries": max_retries, "link": link, "device": device, "stop": stop,
|
||||
"parity": parity, "baud": baud, "data": data})
|
||||
|
||||
def mqtt_node_setting(node):
|
||||
return node_setting(node, json={"client-id": "neuron_aBcDeF", "qos":0, "format": 0,
|
||||
"write-req-topic": f"/neuron/{node}/write/req", "write-resp-topic": f"/neuron/{node}/write/resp",
|
||||
"offline-cache": False, "cache-sync-interval": 100, "host": "broker.emqx.io", "port": 1883, "username": "", "password": "", "ssl": False})
|
||||
@@ -68,3 +68,4 @@ NEU_DATA_8 = 3
|
||||
|
||||
PLUGIN_MODBUS_TCP = "Modbus TCP"
|
||||
PLUGIN_MODBUS_RTU = "Modbus RTU"
|
||||
PLUGIN_MQTT = "MQTT"
|
||||
|
||||
Reference in New Issue
Block a user