mirror of
https://github.com/emqx/neuron.git
synced 2026-10-31 00:19:15 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96986ce10b | ||
|
|
867ab69ff4 | ||
|
|
f402cf3858 | ||
|
|
bd1651f12a | ||
|
|
160f5eb293 | ||
|
|
31ee80f64e | ||
|
|
af8cc2ee2d | ||
|
|
84cfeadf52 | ||
|
|
e84fe85eee | ||
|
|
c0c3cb11b3 | ||
|
|
93c2061b9b | ||
|
|
3fac458370 | ||
|
|
09c21bde58 | ||
|
|
f5191248b5 | ||
|
|
bfcd62252f | ||
|
|
38f8409175 | ||
|
|
b05942da86 | ||
|
|
cf7b4e7548 | ||
|
|
267d5e0a0a | ||
|
|
f163d8acc5 | ||
|
|
45ddf88326 | ||
|
|
cad4570146 | ||
|
|
7871ef1128 | ||
|
|
92a948a483 | ||
|
|
84c4cd9e91 | ||
|
|
ebc4d9f05f | ||
|
|
ff2fc4fe79 | ||
|
|
5a2676b162 | ||
|
|
710948464c | ||
|
|
4e601a8eed | ||
|
|
b7d85049be | ||
|
|
f1b8dd89dc | ||
|
|
b14a221eab | ||
|
|
cb16765b98 | ||
|
|
8a57237285 | ||
|
|
a107c0aebb | ||
|
|
6328fd12da | ||
|
|
69d9c2cc3b | ||
|
|
f32ced4628 | ||
|
|
210a123cba | ||
|
|
e8cf3e4891 | ||
|
|
d0c69b28b1 | ||
|
|
da4757a91f | ||
|
|
c6c176069d | ||
|
|
1eedb1e4cf | ||
|
|
73441f5102 | ||
|
|
2cc9a68548 | ||
|
|
9d586dff2d | ||
|
|
217799aadf | ||
|
|
67c5b17816 | ||
|
|
3bf7a10ac9 | ||
|
|
e7bd8262f6 | ||
|
|
e089d7965e |
@@ -8,7 +8,7 @@ on:
|
||||
- published
|
||||
|
||||
env:
|
||||
VERSION: 2.11.3
|
||||
VERSION: 2.11.5
|
||||
UI_VERSION: 2.6.1
|
||||
BRANCH: v2.11
|
||||
|
||||
|
||||
@@ -185,6 +185,8 @@ file(COPY ${CMAKE_SOURCE_DIR}/default_plugins.json DESTINATION ${CMAKE_BINARY_DI
|
||||
add_subdirectory(plugins/modbus)
|
||||
add_subdirectory(plugins/mqtt)
|
||||
add_subdirectory(plugins/ekuiper)
|
||||
add_subdirectory(plugins/file)
|
||||
add_subdirectory(plugins/monitor)
|
||||
|
||||
add_subdirectory(simulator)
|
||||
|
||||
|
||||
@@ -303,6 +303,7 @@ int neu_conn_tcp_server_wait_msg(neu_conn_t *conn, int fd, void *context,
|
||||
int is_ipv4(const char *ip);
|
||||
int is_ipv6(const char *ip);
|
||||
|
||||
bool neu_conn_is_connected(neu_conn_t *conn);
|
||||
bool neu_conn_is_connected(neu_conn_t *conn);
|
||||
uint16_t neu_conn_udp_act_port(neu_conn_t *conn);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#define NEU_VERSION_MAJOR 2
|
||||
#define NEU_VERSION_MINOR 11
|
||||
#define NEU_VERSION_FIX 3
|
||||
#define NEU_VERSION_FIX 5
|
||||
|
||||
#define NEU_GET_VERSION_MAJOR(V) ((0xffff0000 & V) >> 16)
|
||||
#define NEU_GET_VERSION_MINOR(V) ((0x0000ff00 & V) >> 8)
|
||||
@@ -124,6 +124,14 @@
|
||||
}); \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_NODE_MONITOR_ERR \
|
||||
do { \
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_NODE_NOT_ALLOW_UPDATE, { \
|
||||
neu_http_response(aio, NEU_ERR_NODE_NOT_ALLOW_UPDATE, \
|
||||
result_error); \
|
||||
}); \
|
||||
} while (0)
|
||||
|
||||
extern int default_log_level;
|
||||
extern bool disable_jwt;
|
||||
extern char host_port[32];
|
||||
|
||||
@@ -35,7 +35,7 @@ typedef struct neu_events neu_events_t;
|
||||
* thread.
|
||||
* @return the newly created event.
|
||||
*/
|
||||
neu_events_t *neu_event_new(void);
|
||||
neu_events_t *neu_event_new(const char *name);
|
||||
|
||||
/**
|
||||
* @brief Close a event.
|
||||
|
||||
+134
-35
@@ -60,6 +60,8 @@ typedef enum neu_reqresp_type {
|
||||
NEU_REQ_SUBSCRIBE_GROUPS,
|
||||
NEU_REQ_GET_SUBSCRIBE_GROUP,
|
||||
NEU_RESP_GET_SUBSCRIBE_GROUP,
|
||||
NEU_REQ_GET_DRIVER_SUBSCRIBE_GROUP,
|
||||
NEU_RESP_GET_DRIVER_SUBSCRIBE_GROUP,
|
||||
NEU_REQ_GET_SUB_DRIVER_TAGS,
|
||||
NEU_RESP_GET_SUB_DRIVER_TAGS,
|
||||
|
||||
@@ -128,6 +130,27 @@ typedef enum neu_reqresp_type {
|
||||
|
||||
NEU_REQ_DRIVER_ACTION,
|
||||
NEU_RESP_DRIVER_ACTION,
|
||||
|
||||
NEU_REQ_ADD_NODE_EVENT,
|
||||
NEU_REQ_DEL_NODE_EVENT,
|
||||
NEU_REQ_NODE_CTL_EVENT,
|
||||
NEU_REQ_NODE_SETTING_EVENT,
|
||||
NEU_REQ_ADD_GROUP_EVENT,
|
||||
NEU_REQ_DEL_GROUP_EVENT,
|
||||
NEU_REQ_UPDATE_GROUP_EVENT,
|
||||
NEU_REQ_ADD_TAG_EVENT,
|
||||
NEU_REQ_DEL_TAG_EVENT,
|
||||
NEU_REQ_UPDATE_TAG_EVENT,
|
||||
|
||||
NEU_REQ_ADD_GTAG_EVENT,
|
||||
|
||||
NEU_REQ_ADD_PLUGIN_EVENT,
|
||||
NEU_REQ_DEL_PLUGIN_EVENT,
|
||||
|
||||
NEU_REQ_SUBSCRIBE_GROUP_EVENT,
|
||||
NEU_REQ_UNSUBSCRIBE_GROUP_EVENT,
|
||||
NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT,
|
||||
NEU_REQ_SUBSCRIBE_GROUPS_EVENT,
|
||||
} neu_reqresp_type_e;
|
||||
|
||||
static const char *neu_reqresp_type_string_t[] = {
|
||||
@@ -143,14 +166,17 @@ static const char *neu_reqresp_type_string_t[] = {
|
||||
[NEU_REQ_WRITE_TAGS] = "NEU_REQ_WRITE_TAGS",
|
||||
[NEU_REQ_WRITE_GTAGS] = "NEU_REQ_WRITE_GTAGS",
|
||||
|
||||
[NEU_REQ_SUBSCRIBE_GROUP] = "NEU_REQ_SUBSCRIBE_GROUP",
|
||||
[NEU_REQ_UNSUBSCRIBE_GROUP] = "NEU_REQ_UNSUBSCRIBE_GROUP",
|
||||
[NEU_REQ_UPDATE_SUBSCRIBE_GROUP] = "NEU_REQ_UPDATE_SUBSCRIBE_GROUP",
|
||||
[NEU_REQ_SUBSCRIBE_GROUPS] = "NEU_REQ_SUBSCRIBE_GROUPS",
|
||||
[NEU_REQ_GET_SUBSCRIBE_GROUP] = "NEU_REQ_GET_SUBSCRIBE_GROUP",
|
||||
[NEU_RESP_GET_SUBSCRIBE_GROUP] = "NEU_RESP_GET_SUBSCRIBE_GROUP",
|
||||
[NEU_REQ_GET_SUB_DRIVER_TAGS] = "NEU_REQ_GET_SUB_DRIVER_TAGS",
|
||||
[NEU_RESP_GET_SUB_DRIVER_TAGS] = "NEU_RESP_GET_SUB_DRIVER_TAGS",
|
||||
[NEU_REQ_SUBSCRIBE_GROUP] = "NEU_REQ_SUBSCRIBE_GROUP",
|
||||
[NEU_REQ_UNSUBSCRIBE_GROUP] = "NEU_REQ_UNSUBSCRIBE_GROUP",
|
||||
[NEU_REQ_UPDATE_SUBSCRIBE_GROUP] = "NEU_REQ_UPDATE_SUBSCRIBE_GROUP",
|
||||
[NEU_REQ_SUBSCRIBE_GROUPS] = "NEU_REQ_SUBSCRIBE_GROUPS",
|
||||
[NEU_REQ_GET_SUBSCRIBE_GROUP] = "NEU_REQ_GET_SUBSCRIBE_GROUP",
|
||||
[NEU_RESP_GET_SUBSCRIBE_GROUP] = "NEU_RESP_GET_SUBSCRIBE_GROUP",
|
||||
[NEU_REQ_GET_DRIVER_SUBSCRIBE_GROUP] = "NEU_REQ_GET_DRIVER_SUBSCRIBE_GROUP",
|
||||
[NEU_RESP_GET_DRIVER_SUBSCRIBE_GROUP] =
|
||||
"NEU_RESP_GET_DRIVER_SUBSCRIBE_GROUP",
|
||||
[NEU_REQ_GET_SUB_DRIVER_TAGS] = "NEU_REQ_GET_SUB_DRIVER_TAGS",
|
||||
[NEU_RESP_GET_SUB_DRIVER_TAGS] = "NEU_RESP_GET_SUB_DRIVER_TAGS",
|
||||
|
||||
[NEU_REQ_NODE_INIT] = "NEU_REQ_NODE_INIT",
|
||||
[NEU_REQ_NODE_UNINIT] = "NEU_REQ_NODE_UNINIT",
|
||||
@@ -216,6 +242,25 @@ static const char *neu_reqresp_type_string_t[] = {
|
||||
|
||||
[NEU_REQ_DRIVER_ACTION] = "NEU_REQ_DRIVER_ACTION",
|
||||
[NEU_RESP_DRIVER_ACTION] = "NEU_RESP_DRIVER_ACTION",
|
||||
|
||||
[NEU_REQ_ADD_NODE_EVENT] = "NEU_REQ_ADD_NODE_EVENT",
|
||||
[NEU_REQ_DEL_NODE_EVENT] = "NEU_REQ_DEL_NODE_EVENT",
|
||||
[NEU_REQ_NODE_CTL_EVENT] = "NEU_REQ_NODE_CTL_EVENT",
|
||||
[NEU_REQ_NODE_SETTING_EVENT] = "NEU_REQ_NODE_SETTING_EVENT",
|
||||
[NEU_REQ_ADD_GROUP_EVENT] = "NEU_REQ_ADD_GROUP_EVENT",
|
||||
[NEU_REQ_DEL_GROUP_EVENT] = "NEU_REQ_DEL_GROUP_EVENT",
|
||||
[NEU_REQ_UPDATE_GROUP_EVENT] = "NEU_REQ_UPDATE_GROUP_EVENT",
|
||||
[NEU_REQ_ADD_TAG_EVENT] = "NEU_REQ_ADD_TAG_EVENT",
|
||||
[NEU_REQ_DEL_TAG_EVENT] = "NEU_REQ_DEL_TAG_EVENT",
|
||||
[NEU_REQ_UPDATE_TAG_EVENT] = "NEU_REQ_UPDATE_TAG_EVENT",
|
||||
[NEU_REQ_ADD_GTAG_EVENT] = "NEU_REQ_ADD_GTAG_EVENT",
|
||||
[NEU_REQ_ADD_PLUGIN_EVENT] = "NEU_REQ_ADD_PLUGIN_EVENT",
|
||||
[NEU_REQ_DEL_PLUGIN_EVENT] = "NEU_REQ_DEL_PLUGIN_EVENT",
|
||||
[NEU_REQ_SUBSCRIBE_GROUP_EVENT] = "NEU_REQ_SUBSCRIBE_GROUP_EVENT",
|
||||
[NEU_REQ_UNSUBSCRIBE_GROUP_EVENT] = "NEU_REQ_UNSUBSCRIBE_GROUP_EVENT",
|
||||
[NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT] =
|
||||
"NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT",
|
||||
[NEU_REQ_SUBSCRIBE_GROUPS_EVENT] = "NEU_REQ_SUBSCRIBE_GROUPS_EVENT",
|
||||
};
|
||||
|
||||
inline static const char *neu_reqresp_type_string(neu_reqresp_type_e type)
|
||||
@@ -238,6 +283,7 @@ typedef struct neu_reqresp_head {
|
||||
char receiver[NEU_NODE_NAME_LEN];
|
||||
uint8_t otel_trace_type;
|
||||
uint32_t len;
|
||||
bool monitor;
|
||||
} neu_reqresp_head_t;
|
||||
|
||||
typedef struct neu_resp_error {
|
||||
@@ -326,11 +372,21 @@ typedef struct neu_req_get_node {
|
||||
neu_node_type_e type;
|
||||
char plugin[NEU_PLUGIN_NAME_LEN];
|
||||
char node[NEU_NODE_NAME_LEN];
|
||||
|
||||
struct {
|
||||
bool q_state;
|
||||
int state;
|
||||
bool q_link;
|
||||
int link;
|
||||
bool s_delay;
|
||||
char q_group_name[NEU_GROUP_NAME_LEN];
|
||||
} query;
|
||||
} neu_req_get_node_t;
|
||||
|
||||
typedef struct neu_resp_node_info {
|
||||
char node[NEU_NODE_NAME_LEN];
|
||||
char plugin[NEU_PLUGIN_NAME_LEN];
|
||||
int64_t delay;
|
||||
char node[NEU_NODE_NAME_LEN];
|
||||
char plugin[NEU_PLUGIN_NAME_LEN];
|
||||
} neu_resp_node_info_t;
|
||||
|
||||
typedef struct neu_resp_get_node {
|
||||
@@ -368,6 +424,7 @@ typedef struct neu_req_del_group {
|
||||
|
||||
typedef struct neu_req_get_group {
|
||||
char driver[NEU_NODE_NAME_LEN];
|
||||
char q_group[NEU_GROUP_NAME_LEN];
|
||||
} neu_req_get_group_t;
|
||||
|
||||
typedef struct neu_resp_group_info {
|
||||
@@ -536,6 +593,11 @@ typedef struct neu_req_get_subscribe_group {
|
||||
char group[NEU_GROUP_NAME_LEN];
|
||||
} neu_req_get_subscribe_group_t;
|
||||
|
||||
typedef struct neu_req_get_driver_subscribe_group {
|
||||
char app[NEU_NODE_NAME_LEN];
|
||||
char name[NEU_NODE_NAME_LEN];
|
||||
} neu_req_get_driver_subscribe_group_t;
|
||||
|
||||
typedef struct {
|
||||
char app[NEU_NODE_NAME_LEN];
|
||||
} neu_req_get_sub_driver_tags_t;
|
||||
@@ -548,6 +610,13 @@ typedef struct neu_resp_subscribe_info {
|
||||
char *static_tags;
|
||||
} neu_resp_subscribe_info_t;
|
||||
|
||||
typedef struct neu_resp_driver_subscribe_info {
|
||||
char driver[NEU_NODE_NAME_LEN];
|
||||
char app[NEU_NODE_NAME_LEN];
|
||||
char group[NEU_GROUP_NAME_LEN];
|
||||
bool subscribed;
|
||||
} neu_resp_driver_subscribe_info_t;
|
||||
|
||||
static inline void neu_resp_subscribe_info_fini(neu_resp_subscribe_info_t *info)
|
||||
{
|
||||
free(info->params);
|
||||
@@ -571,7 +640,8 @@ typedef struct {
|
||||
} neu_resp_get_sub_driver_tags_t;
|
||||
|
||||
typedef struct neu_resp_get_subscribe_group {
|
||||
UT_array *groups; // array neu_resp_subscribe_info_t
|
||||
UT_array *groups; // array neu_resp_subscribe_info_t or
|
||||
// neu_resp_driver_subscribe_info_t
|
||||
} neu_resp_get_subscribe_group_t;
|
||||
|
||||
typedef struct neu_req_node_setting {
|
||||
@@ -722,10 +792,11 @@ typedef struct neu_resp_tag_value {
|
||||
typedef neu_resp_tag_value_t neu_tag_value_t;
|
||||
|
||||
typedef struct neu_resp_tag_value_meta {
|
||||
char tag[NEU_TAG_NAME_LEN];
|
||||
neu_dvalue_t value;
|
||||
neu_tag_meta_t metas[NEU_TAG_META_SIZE];
|
||||
neu_datatag_t datatag;
|
||||
char tag[NEU_TAG_NAME_LEN];
|
||||
neu_dvalue_t value;
|
||||
neu_tag_meta_t *metas;
|
||||
int n_meta;
|
||||
neu_datatag_t datatag;
|
||||
} neu_resp_tag_value_meta_t;
|
||||
|
||||
static inline UT_icd *neu_resp_tag_value_meta_icd()
|
||||
@@ -786,10 +857,11 @@ typedef struct {
|
||||
} neu_resp_read_group_t;
|
||||
|
||||
typedef struct neu_resp_tag_value_meta_paginate {
|
||||
char tag[NEU_TAG_NAME_LEN];
|
||||
neu_dvalue_t value;
|
||||
neu_tag_meta_t metas[NEU_TAG_META_SIZE];
|
||||
neu_datatag_t datatag;
|
||||
char tag[NEU_TAG_NAME_LEN];
|
||||
neu_dvalue_t value;
|
||||
neu_tag_meta_t *metas;
|
||||
int n_meta;
|
||||
neu_datatag_t datatag;
|
||||
} neu_resp_tag_value_meta_paginate_t;
|
||||
|
||||
static inline UT_icd *neu_resp_tag_value_meta_paginate_icd()
|
||||
@@ -820,6 +892,13 @@ static inline void neu_resp_read_free(neu_resp_read_group_t *resp)
|
||||
tag_value->value.type < NEU_TYPE_ARRAY_STRING) {
|
||||
free(tag_value->value.value.bools.bools);
|
||||
}
|
||||
|
||||
if (tag_value->metas != NULL) {
|
||||
for (int i = 0; i < tag_value->n_meta; i++) {
|
||||
neu_free_dvalue(&tag_value->metas[i].value);
|
||||
}
|
||||
free(tag_value->metas);
|
||||
}
|
||||
}
|
||||
free(resp->driver);
|
||||
free(resp->group);
|
||||
@@ -837,6 +916,13 @@ neu_resp_read_paginate_free(neu_resp_read_group_paginate_t *resp)
|
||||
tag_value->value.type < NEU_TYPE_ARRAY_STRING) {
|
||||
free(tag_value->value.value.bools.bools);
|
||||
}
|
||||
|
||||
if (tag_value->metas != NULL) {
|
||||
for (int i = 0; i < tag_value->n_meta; i++) {
|
||||
neu_free_dvalue(&tag_value->metas[i].value);
|
||||
}
|
||||
free(tag_value->metas);
|
||||
}
|
||||
}
|
||||
free(resp->driver);
|
||||
free(resp->group);
|
||||
@@ -914,6 +1000,13 @@ static inline void neu_trans_data_free(neu_reqresp_trans_data_t *data)
|
||||
tag_value->value.type < NEU_TYPE_ARRAY_STRING) {
|
||||
free(tag_value->value.value.bools.bools);
|
||||
}
|
||||
|
||||
if (tag_value->metas != NULL) {
|
||||
for (int i = 0; i < tag_value->n_meta; i++) {
|
||||
neu_free_dvalue(&tag_value->metas[i].value);
|
||||
}
|
||||
free(tag_value->metas);
|
||||
}
|
||||
}
|
||||
utarray_free(data->tags);
|
||||
free(data->group);
|
||||
@@ -932,18 +1025,21 @@ static inline void neu_tag_value_to_json(neu_resp_tag_value_meta_t *tag_value,
|
||||
tag_json->name = tag_value->tag;
|
||||
tag_json->error = 0;
|
||||
|
||||
for (int k = 0; k < NEU_TAG_META_SIZE; k++) {
|
||||
if (strlen(tag_value->metas[k].name) > 0) {
|
||||
tag_json->n_meta++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for (int k = 0; k < NEU_TAG_META_SIZE; k++) {
|
||||
// if (strlen(tag_value->metas[k].name) > 0) {
|
||||
// tag_json->n_meta++;
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
tag_json->n_meta = tag_value->n_meta;
|
||||
|
||||
if (tag_json->n_meta > 0) {
|
||||
tag_json->metas = (neu_json_tag_meta_t *) calloc(
|
||||
tag_json->n_meta, sizeof(neu_json_tag_meta_t));
|
||||
}
|
||||
neu_json_metas_to_json(tag_value->metas, NEU_TAG_META_SIZE, tag_json);
|
||||
neu_json_metas_to_json(tag_value->metas, tag_value->n_meta, tag_json);
|
||||
|
||||
tag_json->datatag.bias = tag_value->datatag.bias;
|
||||
|
||||
@@ -1141,18 +1237,21 @@ neu_tag_value_to_json_paginate(neu_resp_tag_value_meta_paginate_t *tag_value,
|
||||
memcpy(tag_json->datatag.meta, tag_value->datatag.meta,
|
||||
NEU_TAG_META_LENGTH);
|
||||
|
||||
for (int k = 0; k < NEU_TAG_META_SIZE; k++) {
|
||||
if (strlen(tag_value->metas[k].name) > 0) {
|
||||
tag_json->n_meta++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for (int k = 0; k < NEU_TAG_META_SIZE; k++) {
|
||||
// if (strlen(tag_value->metas[k].name) > 0) {
|
||||
// tag_json->n_meta++;
|
||||
// } else {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
tag_json->n_meta = tag_value->n_meta;
|
||||
|
||||
if (tag_json->n_meta > 0) {
|
||||
tag_json->metas = (neu_json_tag_meta_t *) calloc(
|
||||
tag_json->n_meta, sizeof(neu_json_tag_meta_t));
|
||||
}
|
||||
neu_json_metas_to_json_paginate(tag_value->metas, NEU_TAG_META_SIZE,
|
||||
neu_json_metas_to_json_paginate(tag_value->metas, tag_value->n_meta,
|
||||
tag_json);
|
||||
|
||||
switch (tag_value->value.type) {
|
||||
|
||||
@@ -155,7 +155,7 @@ typedef struct {
|
||||
uint8_t * ptr;
|
||||
} neu_value_ptr_t;
|
||||
|
||||
#define NEU_VALUE_SIZE 256
|
||||
#define NEU_VALUE_SIZE 1024
|
||||
#define NEU_ARRAY_SIZE 128
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -114,6 +114,8 @@ inline static cid_basictype_e decode_basictype(const char *btype)
|
||||
ret = VisString64;
|
||||
} else if (strcmp(btype, "VisString255") == 0) {
|
||||
ret = VisString255;
|
||||
} else if (strcmp(btype, "VisString65") == 0) {
|
||||
ret = Unicode255;
|
||||
} else if (strcmp(btype, "Octet64") == 0) {
|
||||
ret = Octet64;
|
||||
} else if (strcmp(btype, "Struct") == 0) {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2023 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
--- fix primary key ---
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS old_node_cache;
|
||||
ALTER TABLE node_cache RENAME TO old_node_cache;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS node_cache (
|
||||
node_name TEXT PRIMARY KEY,
|
||||
CACHE TEXT NOT NULL,
|
||||
FOREIGN KEY (node_name) REFERENCES nodes (name) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT OR REPLACE INTO node_cache SELECT * FROM old_node_cache;
|
||||
|
||||
DROP TABLE old_node_cache;
|
||||
|
||||
COMMIT;
|
||||
@@ -234,9 +234,22 @@ void recv_data_callback(void *arg)
|
||||
if (req->singular) {
|
||||
rv = send_write_tag_req(plugin, &req->single, json_str, trace_flag,
|
||||
trace_id, span_id);
|
||||
if (rv == 0) {
|
||||
plog_notice(plugin, "write tag %s.%s on node %s", req->single.group,
|
||||
req->single.tag, req->single.node);
|
||||
}
|
||||
} else {
|
||||
rv = send_write_tags_req(plugin, &req->plural, json_str, trace_flag,
|
||||
trace_id, span_id);
|
||||
if (rv == 0) {
|
||||
if (req->plural.n_tag == 0) {
|
||||
plog_warn(plugin, "no tags to write on node %s",
|
||||
req->plural.node);
|
||||
} else {
|
||||
plog_notice(plugin, "write %d tags on node %s",
|
||||
req->plural.n_tag, req->plural.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != rv) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/plugins")
|
||||
|
||||
set(CMAKE_BUILD_RPATH ./)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/plugins/file/file.json DESTINATION ${CMAKE_BINARY_DIR}/plugins/schema/)
|
||||
|
||||
set(PLUGIN_NAME plugin-file)
|
||||
set(PLUGIN_SOURCES file_plugin.c)
|
||||
add_library(${PLUGIN_NAME} SHARED)
|
||||
target_include_directories(${PLUGIN_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include/neuron)
|
||||
target_sources(${PLUGIN_NAME} PRIVATE ${PLUGIN_SOURCES})
|
||||
target_link_libraries(${PLUGIN_NAME} neuron-base)
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"tag_regex": [
|
||||
{
|
||||
"type": 13,
|
||||
"regex": ""
|
||||
}
|
||||
],
|
||||
"group_interval": 1000
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <neuron.h>
|
||||
|
||||
#include "errcodes.h"
|
||||
|
||||
struct neu_plugin {
|
||||
neu_plugin_common_t common;
|
||||
|
||||
// neu_events_t *events;
|
||||
|
||||
// int file_length;
|
||||
};
|
||||
|
||||
static neu_plugin_t *driver_open(void);
|
||||
|
||||
static int driver_close(neu_plugin_t *plugin);
|
||||
static int driver_init(neu_plugin_t *plugin, bool load);
|
||||
static int driver_uninit(neu_plugin_t *plugin);
|
||||
static int driver_start(neu_plugin_t *plugin);
|
||||
static int driver_stop(neu_plugin_t *plugin);
|
||||
static int driver_config(neu_plugin_t *plugin, const char *config);
|
||||
static int driver_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
void *data);
|
||||
|
||||
static int driver_tag_validator(const neu_datatag_t *tag);
|
||||
static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag);
|
||||
static int driver_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group);
|
||||
static int driver_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
|
||||
neu_value_u value);
|
||||
|
||||
static const neu_plugin_intf_funs_t plugin_intf_funs = {
|
||||
.open = driver_open,
|
||||
.close = driver_close,
|
||||
.init = driver_init,
|
||||
.uninit = driver_uninit,
|
||||
.start = driver_start,
|
||||
.stop = driver_stop,
|
||||
.setting = driver_config,
|
||||
.request = driver_request,
|
||||
|
||||
.driver.validate_tag = driver_validate_tag,
|
||||
.driver.group_timer = driver_group_timer,
|
||||
.driver.group_sync = NULL,
|
||||
.driver.write_tag = driver_write,
|
||||
.driver.tag_validator = driver_tag_validator,
|
||||
.driver.write_tags = NULL,
|
||||
.driver.test_read_tag = NULL,
|
||||
.driver.add_tags = NULL,
|
||||
.driver.load_tags = NULL,
|
||||
.driver.del_tags = NULL,
|
||||
};
|
||||
|
||||
const neu_plugin_module_t neu_plugin_module = {
|
||||
.version = NEURON_PLUGIN_VER_1_0,
|
||||
.schema = "file",
|
||||
.module_name = "File",
|
||||
.module_descr = "The plugin is used to read and write files.",
|
||||
.module_descr_zh = "该插件用于读写文件。",
|
||||
.intf_funs = &plugin_intf_funs,
|
||||
.kind = NEU_PLUGIN_KIND_SYSTEM,
|
||||
.type = NEU_NA_TYPE_DRIVER,
|
||||
.display = true,
|
||||
.single = false,
|
||||
};
|
||||
|
||||
static neu_plugin_t *driver_open(void)
|
||||
{
|
||||
neu_plugin_t *plugin = calloc(1, sizeof(neu_plugin_t));
|
||||
|
||||
neu_plugin_common_init(&plugin->common);
|
||||
|
||||
return plugin;
|
||||
}
|
||||
|
||||
static int driver_close(neu_plugin_t *plugin)
|
||||
{
|
||||
free(plugin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_init(neu_plugin_t *plugin, bool load)
|
||||
{
|
||||
(void) load;
|
||||
plog_notice(plugin, "%s init success", plugin->common.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_uninit(neu_plugin_t *plugin)
|
||||
{
|
||||
plog_notice(plugin, "%s uninit success", plugin->common.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_start(neu_plugin_t *plugin)
|
||||
{
|
||||
neu_adapter_update_metric_cb_t update_metric =
|
||||
plugin->common.adapter_callbacks->update_metric;
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_LAST_RTT_MS, 1, NULL);
|
||||
|
||||
plugin->common.link_state = NEU_NODE_LINK_STATE_CONNECTED;
|
||||
plog_notice(plugin, "start `%s` plugin success", plugin->common.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_stop(neu_plugin_t *plugin)
|
||||
{
|
||||
neu_adapter_update_metric_cb_t update_metric =
|
||||
plugin->common.adapter_callbacks->update_metric;
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_LAST_RTT_MS, 9999, NULL);
|
||||
|
||||
plugin->common.link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
|
||||
plog_notice(plugin, "stop `%s` plugin success", plugin->common.name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int driver_config(neu_plugin_t *plugin, const char *config)
|
||||
{
|
||||
(void) plugin;
|
||||
(void) config;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
void *data)
|
||||
{
|
||||
(void) plugin;
|
||||
(void) head;
|
||||
(void) data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_tag_validator(const neu_datatag_t *tag)
|
||||
{
|
||||
(void) tag;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag)
|
||||
{
|
||||
if (tag->type != NEU_TYPE_STRING) {
|
||||
return NEU_ERR_TAG_TYPE_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
plog_notice(plugin, "validate tag success, name:%s, address:%s, type:%d ",
|
||||
tag->name, tag->address, tag->type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group)
|
||||
{
|
||||
neu_adapter_update_metric_cb_t update_metric =
|
||||
plugin->common.adapter_callbacks->update_metric;
|
||||
|
||||
utarray_foreach(group->tags, neu_datatag_t *, tag)
|
||||
{
|
||||
neu_dvalue_t dvalue = { 0 };
|
||||
|
||||
FILE *fp = fopen(tag->address, "r");
|
||||
if (fp == NULL) {
|
||||
dvalue.type = NEU_TYPE_ERROR;
|
||||
if (errno == ENOENT) {
|
||||
dvalue.value.i32 = NEU_ERR_FILE_NOT_EXIST;
|
||||
} else {
|
||||
dvalue.value.i32 = NEU_ERR_FILE_OPEN_FAILURE;
|
||||
}
|
||||
} else {
|
||||
char *buf = calloc(1, 1024);
|
||||
int ret = fread(buf, 1, 1024, fp);
|
||||
if (ret < 0) {
|
||||
dvalue.type = NEU_TYPE_ERROR;
|
||||
dvalue.value.i32 = NEU_ERR_FILE_READ_FAILURE;
|
||||
} else {
|
||||
dvalue.type = NEU_TYPE_STRING;
|
||||
strncpy(dvalue.value.str, buf, NEU_VALUE_SIZE - 1);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
plugin->common.adapter_callbacks->driver.update(
|
||||
plugin->common.adapter, group->group_name, tag->name, dvalue);
|
||||
}
|
||||
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_SEND_BYTES, 0, NULL);
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_RECV_BYTES, 0, NULL);
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_LAST_RTT_MS, 1, NULL);
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_GROUP_LAST_SEND_MSGS, 1,
|
||||
group->group_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
|
||||
neu_value_u value)
|
||||
{
|
||||
FILE *fp = fopen(tag->address, "w");
|
||||
if (fp == NULL) {
|
||||
if (errno == ENOENT) {
|
||||
plugin->common.adapter_callbacks->driver.write_response(
|
||||
plugin->common.adapter, req, NEU_ERR_FILE_NOT_EXIST);
|
||||
} else {
|
||||
plugin->common.adapter_callbacks->driver.write_response(
|
||||
plugin->common.adapter, req, NEU_ERR_FILE_OPEN_FAILURE);
|
||||
}
|
||||
} else {
|
||||
if (tag->type == NEU_TYPE_STRING) {
|
||||
size_t ret = fwrite(value.str, 1, strlen(value.str), fp);
|
||||
if (ret != strlen(value.str)) {
|
||||
plugin->common.adapter_callbacks->driver.write_response(
|
||||
plugin->common.adapter, req, NEU_ERR_FILE_WRITE_FAILURE);
|
||||
}
|
||||
} else {
|
||||
plugin->common.adapter_callbacks->driver.write_response(
|
||||
plugin->common.adapter, req, NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
plugin->common.adapter_callbacks->driver.write_response(
|
||||
plugin->common.adapter, req, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -102,7 +102,7 @@ static int driver_init(neu_plugin_t *plugin, bool load)
|
||||
{
|
||||
(void) load;
|
||||
plugin->protocol = MODBUS_PROTOCOL_RTU;
|
||||
plugin->events = neu_event_new();
|
||||
plugin->events = neu_event_new(plugin->common.name);
|
||||
plugin->stack = modbus_stack_create((void *) plugin, MODBUS_PROTOCOL_RTU,
|
||||
modbus_send_msg, modbus_value_handle,
|
||||
modbus_write_resp);
|
||||
|
||||
@@ -105,7 +105,7 @@ static int driver_init(neu_plugin_t *plugin, bool load)
|
||||
{
|
||||
(void) load;
|
||||
plugin->protocol = MODBUS_PROTOCOL_TCP;
|
||||
plugin->events = neu_event_new();
|
||||
plugin->events = neu_event_new(plugin->common.name);
|
||||
plugin->stack = modbus_stack_create((void *) plugin, MODBUS_PROTOCOL_TCP,
|
||||
modbus_send_msg, modbus_value_handle,
|
||||
modbus_write_resp);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# neuron monitor plugin
|
||||
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/plugins")
|
||||
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/plugins/monitor/monitor.json DESTINATION ${CMAKE_BINARY_DIR}/plugins/schema/)
|
||||
|
||||
set(src
|
||||
monitor.c
|
||||
monitor_config.c
|
||||
mqtt_handle.c
|
||||
)
|
||||
|
||||
add_library(plugin-monitor SHARED ${src})
|
||||
|
||||
target_include_directories(plugin-monitor PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include/neuron
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
target_link_libraries(plugin-monitor neuron-base nng)
|
||||
target_link_libraries(plugin-monitor ${CMAKE_THREAD_LIBS_INIT})
|
||||
@@ -0,0 +1,431 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "errcodes.h"
|
||||
#include "event/event.h"
|
||||
#include "monitor.h"
|
||||
#include "mqtt_handle.h"
|
||||
#include "utils/http_handler.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
extern const neu_plugin_module_t neu_plugin_module;
|
||||
|
||||
static struct neu_plugin *g_monitor_plugin_;
|
||||
|
||||
static void connect_cb(void *data)
|
||||
{
|
||||
neu_plugin_t *plugin = data;
|
||||
plugin->common.link_state = NEU_NODE_LINK_STATE_CONNECTED;
|
||||
plog_notice(plugin, "plugin `%s` connected", neu_plugin_module.module_name);
|
||||
}
|
||||
|
||||
static void disconnect_cb(void *data)
|
||||
{
|
||||
neu_plugin_t *plugin = data;
|
||||
plugin->common.link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
|
||||
plog_notice(plugin, "plugin `%s` disconnected",
|
||||
neu_plugin_module.module_name);
|
||||
}
|
||||
|
||||
static int config_mqtt_client(neu_plugin_t *plugin, neu_mqtt_client_t *client,
|
||||
const monitor_config_t *config)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (NULL == client) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// set log category as soon as possible to ease debugging
|
||||
rv = neu_mqtt_client_set_zlog_category(client, plugin->common.log);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_set_zlog_category fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = neu_mqtt_client_set_addr(client, config->host, config->port);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_set_host fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = neu_mqtt_client_set_id(client, config->client_id);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_set_id fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = neu_mqtt_client_set_connect_cb(client, connect_cb, plugin);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_set_connect_cb fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = neu_mqtt_client_set_disconnect_cb(client, disconnect_cb, plugin);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_set_disconnect_cb fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (NULL != config->username) {
|
||||
rv = neu_mqtt_client_set_user(client, config->username,
|
||||
config->password);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_set_user fail");
|
||||
}
|
||||
}
|
||||
|
||||
rv = neu_mqtt_client_set_tls(client, config->ssl, config->ca, config->cert,
|
||||
config->key, config->keypass);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_set_tsl fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int heartbeat_timer_cb(void *data)
|
||||
{
|
||||
neu_plugin_t *plugin = data;
|
||||
|
||||
neu_reqresp_head_t header = {
|
||||
.type = NEU_REQ_GET_NODES_STATE,
|
||||
.ctx = plugin,
|
||||
};
|
||||
neu_req_get_nodes_state_t cmd = {};
|
||||
|
||||
return neu_plugin_op(plugin, header, &cmd);
|
||||
}
|
||||
|
||||
static inline void stop_heartbeart_timer(neu_plugin_t *plugin)
|
||||
{
|
||||
if (plugin->heartbeat_timer) {
|
||||
neu_event_del_timer(plugin->events, plugin->heartbeat_timer);
|
||||
plugin->heartbeat_timer = NULL;
|
||||
plog_notice(plugin, "heartbeat timer stopped");
|
||||
}
|
||||
}
|
||||
|
||||
static int start_hearbeat_timer(neu_plugin_t *plugin, uint64_t interval)
|
||||
{
|
||||
neu_event_timer_t *timer = NULL;
|
||||
|
||||
if (0 == interval) {
|
||||
plog_info(plugin, "heartbeat disabled");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (NULL == plugin->events) {
|
||||
plugin->events = neu_event_new(plugin->common.name);
|
||||
if (NULL == plugin->events) {
|
||||
plog_error(plugin, "neu_event_new fail");
|
||||
return NEU_ERR_EINTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
neu_event_timer_param_t param = {
|
||||
.second = interval,
|
||||
.millisecond = 0,
|
||||
.cb = heartbeat_timer_cb,
|
||||
.usr_data = plugin,
|
||||
};
|
||||
|
||||
timer = neu_event_add_timer(plugin->events, param);
|
||||
if (NULL == timer) {
|
||||
plog_error(plugin, "neu_event_add_timer fail");
|
||||
return NEU_ERR_EINTERNAL;
|
||||
}
|
||||
|
||||
end:
|
||||
if (plugin->heartbeat_timer) {
|
||||
neu_event_del_timer(plugin->events, plugin->heartbeat_timer);
|
||||
}
|
||||
plugin->heartbeat_timer = timer;
|
||||
|
||||
plog_notice(plugin, "start_hearbeat_timer interval: %" PRIu64, interval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uninit_timers_and_mqtt(neu_plugin_t *plugin)
|
||||
{
|
||||
stop_heartbeart_timer(plugin);
|
||||
|
||||
if (NULL != plugin->events) {
|
||||
neu_event_close(plugin->events);
|
||||
plugin->events = NULL;
|
||||
}
|
||||
|
||||
if (NULL != plugin->config) {
|
||||
monitor_config_fini(plugin->config);
|
||||
free(plugin->config);
|
||||
plugin->config = NULL;
|
||||
}
|
||||
|
||||
if (NULL != plugin->mqtt_client) {
|
||||
neu_mqtt_client_close(plugin->mqtt_client);
|
||||
neu_mqtt_client_free(plugin->mqtt_client);
|
||||
plugin->mqtt_client = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static neu_plugin_t *monitor_plugin_open(void)
|
||||
{
|
||||
neu_plugin_t *plugin = calloc(1, sizeof(neu_plugin_t));
|
||||
if (NULL == plugin) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
neu_plugin_common_init(&plugin->common);
|
||||
|
||||
g_monitor_plugin_ = plugin;
|
||||
return plugin;
|
||||
}
|
||||
|
||||
static int monitor_plugin_close(neu_plugin_t *plugin)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
plog_notice(plugin, "Success to free plugin: %s",
|
||||
neu_plugin_module.module_name);
|
||||
free(plugin);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int monitor_plugin_init(neu_plugin_t *plugin, bool load)
|
||||
{
|
||||
int rv = 0;
|
||||
(void) plugin;
|
||||
(void) load;
|
||||
|
||||
plog_notice(plugin, "Initialize plugin: %s", neu_plugin_module.module_name);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int monitor_plugin_uninit(neu_plugin_t *plugin)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
uninit_timers_and_mqtt(plugin);
|
||||
|
||||
plog_notice(plugin, "Uninitialize plugin: %s",
|
||||
neu_plugin_module.module_name);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int monitor_plugin_config(neu_plugin_t *plugin, const char *setting)
|
||||
{
|
||||
int rv = 0;
|
||||
const char * plugin_name = neu_plugin_module.module_name;
|
||||
monitor_config_t config = { 0 };
|
||||
|
||||
rv = monitor_config_parse(plugin, setting, &config);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "monitor_config_parse fail");
|
||||
return NEU_ERR_NODE_SETTING_INVALID;
|
||||
}
|
||||
|
||||
if (NULL == plugin->config) {
|
||||
plugin->config = calloc(1, sizeof(*plugin->config));
|
||||
if (NULL == plugin->config) {
|
||||
plog_error(plugin, "calloc monitor config fail");
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == plugin->mqtt_client) {
|
||||
plugin->mqtt_client = neu_mqtt_client_new(NEU_MQTT_VERSION_V311);
|
||||
if (NULL == plugin->mqtt_client) {
|
||||
plog_error(plugin, "neu_mqtt_client_new fail");
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto error;
|
||||
}
|
||||
} else if (neu_mqtt_client_is_open(plugin->mqtt_client)) {
|
||||
rv = neu_mqtt_client_close(plugin->mqtt_client);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "neu_mqtt_client_close fail");
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
rv = config_mqtt_client(plugin, plugin->mqtt_client, &config);
|
||||
if (0 != rv) {
|
||||
rv = NEU_ERR_MQTT_INIT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (plugin->started && 0 != neu_mqtt_client_open(plugin->mqtt_client)) {
|
||||
plog_error(plugin, "neu_mqtt_client_open fail");
|
||||
rv = NEU_ERR_MQTT_CONNECT_FAILURE;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (plugin->started &&
|
||||
0 != start_hearbeat_timer(plugin, config.heartbeat_interval)) {
|
||||
plog_error(plugin, "start_hearbeat_timer fail");
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
monitor_config_fini(plugin->config);
|
||||
memmove(plugin->config, &config, sizeof(config));
|
||||
// `config` moved, do not call monitor_config_fini
|
||||
|
||||
plog_notice(plugin, "config plugin `%s` success", plugin_name);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
plog_error(plugin, "config plugin `%s` fail", plugin_name);
|
||||
monitor_config_fini(&config);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int monitor_plugin_request(neu_plugin_t * plugin,
|
||||
neu_reqresp_head_t *header, void *data)
|
||||
{
|
||||
(void) plugin;
|
||||
|
||||
switch (header->type) {
|
||||
case NEU_RESP_ERROR: {
|
||||
neu_resp_error_t *resp_err = (neu_resp_error_t *) data;
|
||||
nlog_warn("recv error code: %d", resp_err->error);
|
||||
break;
|
||||
}
|
||||
case NEU_RESP_GET_NODES_STATE: {
|
||||
handle_nodes_state(header->ctx, (neu_resp_get_nodes_state_t *) data);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_NODE_EVENT:
|
||||
case NEU_REQ_DEL_NODE_EVENT:
|
||||
case NEU_REQ_NODE_CTL_EVENT:
|
||||
case NEU_REQ_NODE_SETTING_EVENT:
|
||||
case NEU_REQ_ADD_GROUP_EVENT:
|
||||
case NEU_REQ_DEL_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_GROUP_EVENT:
|
||||
case NEU_REQ_ADD_TAG_EVENT:
|
||||
case NEU_REQ_DEL_TAG_EVENT:
|
||||
case NEU_REQ_UPDATE_TAG_EVENT:
|
||||
case NEU_REQ_ADD_GTAG_EVENT:
|
||||
case NEU_REQ_ADD_PLUGIN_EVENT:
|
||||
case NEU_REQ_DEL_PLUGIN_EVENT:
|
||||
case NEU_REQ_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UNSUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_SUBSCRIBE_GROUPS_EVENT: {
|
||||
handle_events(plugin, header->type, data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
nlog_warn("recv unsupported msg: %s",
|
||||
neu_reqresp_type_string(header->type));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int monitor_plugin_start(neu_plugin_t *plugin)
|
||||
{
|
||||
int rv = 0;
|
||||
const char *plugin_name = neu_plugin_module.module_name;
|
||||
|
||||
if (NULL == plugin->mqtt_client) {
|
||||
plog_notice(plugin, "mqtt client is NULL");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (0 != neu_mqtt_client_open(plugin->mqtt_client)) {
|
||||
plog_error(plugin, "neu_mqtt_client_open fail");
|
||||
rv = NEU_ERR_MQTT_CONNECT_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (0 != start_hearbeat_timer(plugin, plugin->config->heartbeat_interval)) {
|
||||
plog_error(plugin, "start_hearbeat_timer fail");
|
||||
neu_mqtt_client_close(plugin->mqtt_client);
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
if (0 == rv) {
|
||||
plugin->started = true;
|
||||
plog_notice(plugin, "start plugin `%s` success", plugin_name);
|
||||
} else {
|
||||
plog_error(plugin, "start plugin `%s` failed, error %d", plugin_name,
|
||||
rv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int monitor_plugin_stop(neu_plugin_t *plugin)
|
||||
{
|
||||
if (plugin->mqtt_client) {
|
||||
neu_mqtt_client_close(plugin->mqtt_client);
|
||||
plog_notice(plugin, "mqtt client closed");
|
||||
}
|
||||
|
||||
stop_heartbeart_timer(plugin);
|
||||
plugin->started = false;
|
||||
plog_notice(plugin, "stop plugin `%s` success",
|
||||
neu_plugin_module.module_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const neu_plugin_intf_funs_t plugin_intf_funs = {
|
||||
.open = monitor_plugin_open,
|
||||
.close = monitor_plugin_close,
|
||||
.init = monitor_plugin_init,
|
||||
.uninit = monitor_plugin_uninit,
|
||||
.start = monitor_plugin_start,
|
||||
.stop = monitor_plugin_stop,
|
||||
.setting = monitor_plugin_config,
|
||||
.request = monitor_plugin_request,
|
||||
};
|
||||
|
||||
#define DEFAULT_MONITOR_PLUGIN_DESCR \
|
||||
"Builtin plugin for Neuron monitoring and alerting"
|
||||
#define DEFAULT_MONITOR_PLUGIN_DESCR_ZH "内置监控与告警插件"
|
||||
|
||||
const neu_plugin_module_t neu_plugin_module = {
|
||||
.version = NEURON_PLUGIN_VER_1_0,
|
||||
.schema = "monitor",
|
||||
.module_name = "Monitor",
|
||||
.module_descr = DEFAULT_MONITOR_PLUGIN_DESCR,
|
||||
.module_descr_zh = DEFAULT_MONITOR_PLUGIN_DESCR_ZH,
|
||||
.intf_funs = &plugin_intf_funs,
|
||||
.kind = NEU_PLUGIN_KIND_SYSTEM,
|
||||
.type = NEU_NA_TYPE_APP,
|
||||
.display = true,
|
||||
.single = true,
|
||||
.single_name = "monitor",
|
||||
};
|
||||
|
||||
neu_plugin_t *neu_monitor_get_plugin()
|
||||
{
|
||||
return g_monitor_plugin_;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#ifndef NEU_PLUGIN_MONITOR_H
|
||||
#define NEU_PLUGIN_MONITOR_H
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <nng/nng.h>
|
||||
#include <nng/supplemental/http/http.h>
|
||||
|
||||
#include "adapter.h"
|
||||
#include "connection/mqtt_client.h"
|
||||
#include "event/event.h"
|
||||
#include "monitor_config.h"
|
||||
#include "plugin.h"
|
||||
|
||||
struct neu_plugin {
|
||||
neu_plugin_common_t common;
|
||||
bool started;
|
||||
neu_events_t * events;
|
||||
neu_event_timer_t * heartbeat_timer;
|
||||
monitor_config_t * config;
|
||||
neu_mqtt_client_t * mqtt_client;
|
||||
};
|
||||
|
||||
neu_plugin_t *neu_monitor_get_plugin();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,169 @@
|
||||
{
|
||||
"client-id": {
|
||||
"name": "Client ID",
|
||||
"name_zh": "客户端 ID",
|
||||
"description": "MQTT client ID",
|
||||
"description_zh": "MQTT 客户端 ID",
|
||||
"type": "string",
|
||||
"attribute": "required",
|
||||
"default": "neuron_monitor_${random_str}",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"event-topic-prefix": {
|
||||
"name": "Event Topic Prefix",
|
||||
"name_zh": "事件主题前缀",
|
||||
"description": "Prefix of the topics to which publish event messages.",
|
||||
"description_zh": "事件消息发布的主题前缀",
|
||||
"type": "string",
|
||||
"attribute": "required",
|
||||
"default": "/neuron/monitor/${random_str}",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"heartbeat-interval": {
|
||||
"name": "Heartbeat Interval",
|
||||
"name_zh": "心跳间隔",
|
||||
"description": "Interval in seconds between two heartbeat messages. Setting to zero will disable heartbeat monitoring.(seconds)",
|
||||
"description_zh": "每个心跳消息之间的间隔时间(秒),设置为 0 将禁用心跳消息。",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 0,
|
||||
"valid": {
|
||||
"min": 0
|
||||
}
|
||||
},
|
||||
"heartbeat-topic": {
|
||||
"name": "Heartbeat Topic",
|
||||
"name_zh": "心跳主题",
|
||||
"description": "Topic to which publish heartbeat messages.",
|
||||
"description_zh": "心跳消息发布的主题",
|
||||
"type": "string",
|
||||
"attribute": "required",
|
||||
"default": "/neuron/heartbeat/${random_str}",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"name": "Broker Host",
|
||||
"name_zh": "服务器地址",
|
||||
"description": "MQTT broker host",
|
||||
"description_zh": "MQTT 服务器地址",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"default": "broker.emqx.io",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"port": {
|
||||
"name": "Broker Port",
|
||||
"name_zh": "服务器端口",
|
||||
"description": "MQTT broker port",
|
||||
"description_zh": "MQTT 服务器端口",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 1883,
|
||||
"valid": {
|
||||
"min": 1024,
|
||||
"max": 65535
|
||||
}
|
||||
},
|
||||
"username": {
|
||||
"name": "Username",
|
||||
"name_zh": "用户名",
|
||||
"description": "MQTT user name",
|
||||
"description_zh": "MQTT 用户名",
|
||||
"attribute": "optional",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
"name": "Password",
|
||||
"name_zh": "密码",
|
||||
"description": "MQTT user password",
|
||||
"description_zh": "MQTT 用户密码",
|
||||
"attribute": "optional",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"ssl": {
|
||||
"name": "SSL",
|
||||
"name_zh": "SSL",
|
||||
"description": "Enable SSL connection",
|
||||
"description_zh": "是否启用 SSL 连接",
|
||||
"attribute": "optional",
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"valid": {}
|
||||
},
|
||||
"ca": {
|
||||
"name": "CA",
|
||||
"name_zh": "CA 证书",
|
||||
"description": "CA certificate which signs the server certificate",
|
||||
"description_zh": "签发服务器证书的 CA 证书",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
},
|
||||
"cert": {
|
||||
"name": "Client Cert",
|
||||
"name_zh": "客户端证书",
|
||||
"description": "Client x509 certificate when using two way authentication",
|
||||
"description_zh": "使用双向认证时,客户端的 x509 证书",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
},
|
||||
"key": {
|
||||
"name": "Client Private Key",
|
||||
"name_zh": "客户端私钥",
|
||||
"description": "Client private key when using two way authentication",
|
||||
"description_zh": "使用双向认证时,客户端的私钥",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
},
|
||||
"keypass": {
|
||||
"name": "Client Private Key Password",
|
||||
"name_zh": "客户端私钥密码",
|
||||
"description": "Client private key password when using two way authentication with an encrypted client private key",
|
||||
"description_zh": "使用加密的客户端私钥进行双向认证时,客户端私钥的密码",
|
||||
"attribute": "optional",
|
||||
"type": "string",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 256
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#include "json/json.h"
|
||||
#include "json/neu_json_param.h"
|
||||
|
||||
#include "utils/asprintf.h"
|
||||
#include "utils/base64.h"
|
||||
#include "utils/log.h"
|
||||
|
||||
#include "monitor.h"
|
||||
#include "monitor_config.h"
|
||||
|
||||
#define MB 1000000
|
||||
|
||||
static inline int decode_b64_param(neu_plugin_t *plugin, neu_json_elem_t *el)
|
||||
{
|
||||
int len = 0;
|
||||
char *s = (char *) neu_decode64(&len, el->v.val_str);
|
||||
|
||||
if (NULL == s) {
|
||||
plog_error(plugin, "setting %s invalid base64", el->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 == len) {
|
||||
plog_error(plugin, "setting empty %s", el->name);
|
||||
free(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(el->v.val_str);
|
||||
el->v.val_str = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int parse_b64_param(neu_plugin_t *plugin, const char *setting,
|
||||
neu_json_elem_t *el)
|
||||
{
|
||||
if (0 != neu_parse_param(setting, NULL, 1, el)) {
|
||||
plog_error(plugin, "setting no %s", el->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != decode_b64_param(plugin, el)) {
|
||||
free(el->v.val_str);
|
||||
el->v.val_str = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting,
|
||||
neu_json_elem_t *ssl, neu_json_elem_t *ca,
|
||||
neu_json_elem_t *cert, neu_json_elem_t *key,
|
||||
neu_json_elem_t *keypass)
|
||||
{
|
||||
// ssl, optional
|
||||
int ret = neu_parse_param(setting, NULL, 1, ssl);
|
||||
if (0 != ret) {
|
||||
plog_notice(plugin, "setting no ssl");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (false == ssl->v.val_bool) {
|
||||
plog_notice(plugin, "setting ssl disabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ca, optional
|
||||
ret = neu_parse_param(setting, NULL, 1, ca);
|
||||
if (0 != ret) {
|
||||
plog_notice(plugin, "setting no ca");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 != decode_b64_param(plugin, ca)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// cert, optional
|
||||
ret = neu_parse_param(setting, NULL, 1, cert);
|
||||
if (0 != ret) {
|
||||
plog_notice(plugin, "setting no cert");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 != decode_b64_param(plugin, cert)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// key, required if cert enable
|
||||
ret = parse_b64_param(plugin, setting, key);
|
||||
if (0 != ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// keypass, optional
|
||||
ret = neu_parse_param(setting, NULL, 1, keypass);
|
||||
if (0 != ret) {
|
||||
plog_notice(plugin, "setting no keypass");
|
||||
} else if (0 == strlen(keypass->v.val_str)) {
|
||||
plog_error(plugin, "setting invalid keypass");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_event_topics(monitor_config_t *config, const char *prefix)
|
||||
{
|
||||
char *node_add_topic = NULL;
|
||||
char *node_del_topic = NULL;
|
||||
char *node_ctl_topic = NULL;
|
||||
char *node_setting_topic = NULL;
|
||||
char *group_add_topic = NULL;
|
||||
char *group_del_topic = NULL;
|
||||
char *group_update_topic = NULL;
|
||||
char *tag_add_topic = NULL;
|
||||
char *tag_del_topic = NULL;
|
||||
char *tag_update_topic = NULL;
|
||||
char *gtag_add_topic = NULL;
|
||||
char *plugin_add_topic = NULL;
|
||||
char *plugin_del_topic = NULL;
|
||||
char *group_subscribe_topic = NULL;
|
||||
char *group_unsubscribe_topic = NULL;
|
||||
char *group_update_subscribe_topic = NULL;
|
||||
char *groups_subscribe_topic = NULL;
|
||||
|
||||
neu_asprintf(&node_add_topic, "%s/node/add", prefix);
|
||||
if (NULL == node_add_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&node_del_topic, "%s/node/delete", prefix);
|
||||
if (NULL == node_del_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&node_ctl_topic, "%s/node/ctl", prefix);
|
||||
if (NULL == node_ctl_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&node_setting_topic, "%s/node/setting", prefix);
|
||||
if (NULL == node_setting_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&group_add_topic, "%s/group/add", prefix);
|
||||
if (NULL == group_add_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&group_del_topic, "%s/group/delete", prefix);
|
||||
if (NULL == group_del_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&group_update_topic, "%s/group/update", prefix);
|
||||
if (NULL == group_update_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&tag_add_topic, "%s/tag/add", prefix);
|
||||
if (NULL == tag_add_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&tag_del_topic, "%s/tag/delete", prefix);
|
||||
if (NULL == tag_del_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&tag_update_topic, "%s/tag/update", prefix);
|
||||
if (NULL == tag_update_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(>ag_add_topic, "%s/gtag/add", prefix);
|
||||
if (NULL == gtag_add_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&plugin_add_topic, "%s/plugin/add", prefix);
|
||||
if (NULL == plugin_add_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&plugin_del_topic, "%s/plugin/delete", prefix);
|
||||
if (NULL == plugin_del_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&group_subscribe_topic, "%s/group/subscribe", prefix);
|
||||
if (NULL == group_subscribe_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&group_unsubscribe_topic, "%s/group/unsubscribe", prefix);
|
||||
if (NULL == group_unsubscribe_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&group_update_subscribe_topic, "%s/group/update/subscribe",
|
||||
prefix);
|
||||
if (NULL == group_update_subscribe_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
neu_asprintf(&groups_subscribe_topic, "%s/groups/subscribe", prefix);
|
||||
if (NULL == groups_subscribe_topic) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
config->node_add_topic = node_add_topic;
|
||||
config->node_del_topic = node_del_topic;
|
||||
config->node_ctl_topic = node_ctl_topic;
|
||||
config->node_setting_topic = node_setting_topic;
|
||||
config->group_add_topic = group_add_topic;
|
||||
config->group_del_topic = group_del_topic;
|
||||
config->group_update_topic = group_update_topic;
|
||||
config->tag_add_topic = tag_add_topic;
|
||||
config->tag_del_topic = tag_del_topic;
|
||||
config->tag_update_topic = tag_update_topic;
|
||||
config->gtag_add_topic = gtag_add_topic;
|
||||
config->plugin_add_topic = plugin_add_topic;
|
||||
config->plugin_del_topic = plugin_del_topic;
|
||||
config->group_subscribe_topic = group_subscribe_topic;
|
||||
config->group_unsubscribe_topic = group_unsubscribe_topic;
|
||||
config->group_update_subscribe_topic = group_update_subscribe_topic;
|
||||
config->groups_subscribe_topic = groups_subscribe_topic;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(groups_subscribe_topic);
|
||||
free(group_update_subscribe_topic);
|
||||
free(group_unsubscribe_topic);
|
||||
free(group_subscribe_topic);
|
||||
free(plugin_del_topic);
|
||||
free(plugin_add_topic);
|
||||
free(gtag_add_topic);
|
||||
free(tag_update_topic);
|
||||
free(tag_del_topic);
|
||||
free(tag_add_topic);
|
||||
free(group_update_topic);
|
||||
free(group_del_topic);
|
||||
free(group_add_topic);
|
||||
free(node_setting_topic);
|
||||
free(node_ctl_topic);
|
||||
free(node_del_topic);
|
||||
free(node_add_topic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int monitor_config_parse(neu_plugin_t *plugin, const char *setting,
|
||||
monitor_config_t *config)
|
||||
{
|
||||
int ret = 0;
|
||||
char * err_param = NULL;
|
||||
const char *placeholder = "********";
|
||||
|
||||
neu_json_elem_t client_id = { .name = "client-id", .t = NEU_JSON_STR };
|
||||
neu_json_elem_t event_topic_prefix = { .name = "event-topic-prefix",
|
||||
.t = NEU_JSON_STR };
|
||||
neu_json_elem_t heartbeat_interval = { .name = "heartbeat-interval",
|
||||
.t = NEU_JSON_INT };
|
||||
neu_json_elem_t heartbeat_topic = { .name = "heartbeat-topic",
|
||||
.t = NEU_JSON_STR };
|
||||
neu_json_elem_t host = { .name = "host", .t = NEU_JSON_STR };
|
||||
neu_json_elem_t port = { .name = "port", .t = NEU_JSON_INT };
|
||||
neu_json_elem_t username = { .name = "username", .t = NEU_JSON_STR };
|
||||
neu_json_elem_t password = { .name = "password", .t = NEU_JSON_STR };
|
||||
neu_json_elem_t ssl = { .name = "ssl", .t = NEU_JSON_BOOL };
|
||||
neu_json_elem_t ca = { .name = "ca", .t = NEU_JSON_STR };
|
||||
neu_json_elem_t cert = { .name = "cert", .t = NEU_JSON_STR };
|
||||
neu_json_elem_t key = { .name = "key", .t = NEU_JSON_STR };
|
||||
neu_json_elem_t keypass = { .name = "keypass", .t = NEU_JSON_STR };
|
||||
|
||||
if (NULL == setting || NULL == config) {
|
||||
plog_error(plugin, "invalid argument, null pointer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret =
|
||||
neu_parse_param(setting, &err_param, 6, &client_id, &event_topic_prefix,
|
||||
&heartbeat_interval, &heartbeat_topic, &host, &port);
|
||||
if (0 != ret) {
|
||||
plog_error(plugin, "parsing setting fail, key: `%s`", err_param);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// client-id, required
|
||||
if (0 == strlen(client_id.v.val_str)) {
|
||||
plog_error(plugin, "setting empty client-id");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// heartbeat-interval, required
|
||||
if (0 > heartbeat_interval.v.val_int) {
|
||||
plog_error(plugin, "setting negative heartbeat-interval:%" PRIi64,
|
||||
heartbeat_interval.v.val_int);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// heartbeat-topic, required
|
||||
if (0 == strlen(heartbeat_topic.v.val_str)) {
|
||||
plog_error(plugin, "setting empty heartbeat-topic");
|
||||
goto error;
|
||||
}
|
||||
|
||||
// host, required
|
||||
if (0 == strlen(host.v.val_str)) {
|
||||
plog_error(plugin, "setting invalid host: `%s`", host.v.val_str);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// port, required
|
||||
if (0 == port.v.val_int || port.v.val_int > 65535) {
|
||||
plog_error(plugin, "setting invalid port: %" PRIi64, port.v.val_int);
|
||||
goto error;
|
||||
}
|
||||
|
||||
// username, optional
|
||||
ret = neu_parse_param(setting, NULL, 1, &username);
|
||||
if (0 != ret) {
|
||||
plog_notice(plugin, "setting no username");
|
||||
}
|
||||
|
||||
// password, optional
|
||||
ret = neu_parse_param(setting, NULL, 1, &password);
|
||||
if (0 != ret) {
|
||||
plog_notice(plugin, "setting no password");
|
||||
}
|
||||
|
||||
ret = parse_ssl_params(plugin, setting, &ssl, &ca, &cert, &key, &keypass);
|
||||
if (0 != ret) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = make_event_topics(config, event_topic_prefix.v.val_str);
|
||||
if (0 != ret) {
|
||||
plog_error(plugin, "make event topics fail");
|
||||
goto error;
|
||||
}
|
||||
|
||||
config->client_id = client_id.v.val_str;
|
||||
config->event_topic_prefix = event_topic_prefix.v.val_str;
|
||||
config->heartbeat_interval = heartbeat_interval.v.val_int;
|
||||
config->heartbeat_topic = heartbeat_topic.v.val_str;
|
||||
config->host = host.v.val_str;
|
||||
config->port = port.v.val_int;
|
||||
config->username = username.v.val_str;
|
||||
config->password = password.v.val_str;
|
||||
config->ssl = ssl.v.val_bool;
|
||||
config->ca = ca.v.val_str;
|
||||
config->cert = cert.v.val_str;
|
||||
config->key = key.v.val_str;
|
||||
config->keypass = keypass.v.val_str;
|
||||
|
||||
plog_notice(plugin, "config client-id : %s", config->client_id);
|
||||
plog_notice(plugin, "config event-topic-prefix: %s",
|
||||
config->event_topic_prefix);
|
||||
plog_notice(plugin, "config heartbeat-interval: %" PRIu64,
|
||||
config->heartbeat_interval);
|
||||
plog_notice(plugin, "config heartbeat-topic : %s",
|
||||
config->heartbeat_topic);
|
||||
plog_notice(plugin, "config host : %s", config->host);
|
||||
plog_notice(plugin, "config port : %" PRIu16, config->port);
|
||||
|
||||
if (config->username) {
|
||||
plog_notice(plugin, "config username : %s", config->username);
|
||||
}
|
||||
if (config->password) {
|
||||
plog_notice(plugin, "config password : %s",
|
||||
0 == strlen(config->password) ? "" : placeholder);
|
||||
}
|
||||
|
||||
plog_notice(plugin, "config ssl : %d", config->ssl);
|
||||
if (config->ca) {
|
||||
plog_notice(plugin, "config ca : %s", placeholder);
|
||||
}
|
||||
if (config->cert) {
|
||||
plog_notice(plugin, "config cert : %s", placeholder);
|
||||
}
|
||||
if (config->key) {
|
||||
plog_notice(plugin, "config key : %s", placeholder);
|
||||
}
|
||||
if (config->keypass) {
|
||||
plog_notice(plugin, "config keypass : %s", placeholder);
|
||||
}
|
||||
|
||||
plog_notice(plugin, "node add event topic : %s",
|
||||
config->node_add_topic);
|
||||
plog_notice(plugin, "node del event topic : %s",
|
||||
config->node_del_topic);
|
||||
plog_notice(plugin, "node ctl event topic : %s",
|
||||
config->node_ctl_topic);
|
||||
plog_notice(plugin, "node setting event topic : %s",
|
||||
config->node_setting_topic);
|
||||
plog_notice(plugin, "group add topic : %s",
|
||||
config->group_add_topic);
|
||||
plog_notice(plugin, "group del topic : %s",
|
||||
config->group_del_topic);
|
||||
plog_notice(plugin, "group update topic : %s",
|
||||
config->group_update_topic);
|
||||
plog_notice(plugin, "tag add topic : %s", config->tag_add_topic);
|
||||
plog_notice(plugin, "tag del topic : %s", config->tag_del_topic);
|
||||
plog_notice(plugin, "tag update topic : %s",
|
||||
config->tag_update_topic);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(err_param);
|
||||
free(event_topic_prefix.v.val_str);
|
||||
free(heartbeat_topic.v.val_str);
|
||||
free(host.v.val_str);
|
||||
free(username.v.val_str);
|
||||
free(password.v.val_str);
|
||||
free(ca.v.val_str);
|
||||
free(cert.v.val_str);
|
||||
free(key.v.val_str);
|
||||
free(keypass.v.val_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void monitor_config_fini(monitor_config_t *config)
|
||||
{
|
||||
if (NULL == config) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(config->client_id);
|
||||
free(config->event_topic_prefix);
|
||||
free(config->heartbeat_topic);
|
||||
free(config->host);
|
||||
free(config->username);
|
||||
free(config->password);
|
||||
free(config->ca);
|
||||
free(config->cert);
|
||||
free(config->key);
|
||||
free(config->keypass);
|
||||
|
||||
free(config->node_add_topic);
|
||||
free(config->node_del_topic);
|
||||
free(config->node_ctl_topic);
|
||||
free(config->node_setting_topic);
|
||||
free(config->group_add_topic);
|
||||
free(config->group_del_topic);
|
||||
free(config->group_update_topic);
|
||||
free(config->tag_add_topic);
|
||||
free(config->tag_del_topic);
|
||||
free(config->tag_update_topic);
|
||||
free(config->groups_subscribe_topic);
|
||||
free(config->group_update_subscribe_topic);
|
||||
free(config->group_unsubscribe_topic);
|
||||
free(config->group_subscribe_topic);
|
||||
free(config->plugin_del_topic);
|
||||
free(config->plugin_add_topic);
|
||||
free(config->gtag_add_topic);
|
||||
|
||||
memset(config, 0, sizeof(*config));
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#ifndef NEURON_PLUGIN_MONITOR_CONFIG_H
|
||||
#define NEURON_PLUGIN_MONITOR_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "plugin.h"
|
||||
|
||||
typedef struct {
|
||||
char * client_id; // client id
|
||||
char * event_topic_prefix; // event topic prefix
|
||||
uint64_t heartbeat_interval; // heartbeat interval
|
||||
char * heartbeat_topic; // heartbeat topic
|
||||
char * host; // broker host
|
||||
uint16_t port; // broker port
|
||||
char * username; // user name
|
||||
char * password; // user password
|
||||
bool ssl; // ssl flag
|
||||
char * ca; // CA
|
||||
char * cert; // client cert
|
||||
char * key; // client key
|
||||
char * keypass; // client key password
|
||||
|
||||
// event topics generated according to event_topic_prefix
|
||||
char *node_add_topic;
|
||||
char *node_del_topic;
|
||||
char *node_ctl_topic;
|
||||
char *node_setting_topic;
|
||||
char *group_add_topic;
|
||||
char *group_del_topic;
|
||||
char *group_update_topic;
|
||||
char *tag_add_topic;
|
||||
char *tag_del_topic;
|
||||
char *tag_update_topic;
|
||||
char *gtag_add_topic;
|
||||
char *plugin_add_topic;
|
||||
char *plugin_del_topic;
|
||||
char *group_subscribe_topic;
|
||||
char *group_unsubscribe_topic;
|
||||
char *group_update_subscribe_topic;
|
||||
char *groups_subscribe_topic;
|
||||
} monitor_config_t;
|
||||
|
||||
int monitor_config_parse(neu_plugin_t *plugin, const char *setting,
|
||||
monitor_config_t *config);
|
||||
void monitor_config_fini(monitor_config_t *config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,439 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#include "connection/mqtt_client.h"
|
||||
#include "errcodes.h"
|
||||
#include "version.h"
|
||||
#include "json/neu_json_mqtt.h"
|
||||
#include "json/neu_json_rw.h"
|
||||
|
||||
#include "parser/neu_json_group_config.h"
|
||||
#include "parser/neu_json_node.h"
|
||||
#include "parser/neu_json_plugin.h"
|
||||
#include "parser/neu_json_tag.h"
|
||||
|
||||
#include "monitor.h"
|
||||
#include "mqtt_handle.h"
|
||||
|
||||
static char *generate_heartbeat_json(neu_plugin_t *plugin, UT_array *states)
|
||||
{
|
||||
(void) plugin;
|
||||
char * version = NEURON_VERSION;
|
||||
neu_json_states_head_t header = { .version = version,
|
||||
.timpstamp = global_timestamp };
|
||||
neu_json_states_t json = { 0 };
|
||||
char * json_str = NULL;
|
||||
|
||||
json.n_state = utarray_len(states);
|
||||
json.states = calloc(json.n_state, sizeof(neu_json_node_state_t));
|
||||
if (NULL == json.states) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
utarray_foreach(states, neu_nodes_state_t *, state)
|
||||
{
|
||||
int index = utarray_eltidx(states, state);
|
||||
json.states[index].node = state->node;
|
||||
json.states[index].link = state->state.link;
|
||||
json.states[index].running = state->state.running;
|
||||
}
|
||||
|
||||
neu_json_encode_with_mqtt(&json, neu_json_encode_states_resp, &header,
|
||||
neu_json_encode_state_header_resp, &json_str);
|
||||
|
||||
free(json.states);
|
||||
return json_str;
|
||||
}
|
||||
|
||||
static char *generate_event_json(neu_plugin_t *plugin, neu_reqresp_type_e event,
|
||||
void *data, char **topic_p)
|
||||
{
|
||||
char *json_str = NULL;
|
||||
union {
|
||||
neu_json_add_node_req_t add_node;
|
||||
neu_json_del_node_req_t del_node;
|
||||
neu_json_node_ctl_req_t node_ctl;
|
||||
neu_json_node_setting_req_t node_setting;
|
||||
neu_json_add_group_config_req_t add_grp;
|
||||
neu_json_del_group_config_req_t del_grp;
|
||||
neu_json_update_group_config_req_t update_grp;
|
||||
neu_json_add_tags_req_t add_tags;
|
||||
neu_json_del_tags_req_t del_tags;
|
||||
neu_json_subscribe_req_t sub_grp;
|
||||
neu_json_unsubscribe_req_t unsub_grp;
|
||||
neu_json_subscribe_groups_req_t sub_grps;
|
||||
neu_json_add_plugin_req_t add_plugin;
|
||||
neu_json_del_plugin_req_t del_plugin;
|
||||
neu_json_add_gtags_req_t add_gtag;
|
||||
} json_req = {};
|
||||
|
||||
switch (event) {
|
||||
case NEU_REQ_ADD_NODE_EVENT: {
|
||||
neu_req_add_node_t *add_node = data;
|
||||
json_req.add_node.name = add_node->node;
|
||||
json_req.add_node.plugin = add_node->plugin;
|
||||
*topic_p = plugin->config->node_add_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_add_node_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_DEL_NODE_EVENT: {
|
||||
neu_req_del_node_t *del_node = data;
|
||||
json_req.del_node.name = del_node->node;
|
||||
*topic_p = plugin->config->node_del_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_del_node_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_NODE_CTL_EVENT: {
|
||||
neu_req_node_ctl_t *node_ctl = data;
|
||||
json_req.node_ctl.node = node_ctl->node;
|
||||
json_req.node_ctl.cmd = node_ctl->ctl;
|
||||
*topic_p = plugin->config->node_ctl_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_node_ctl_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_NODE_SETTING_EVENT: {
|
||||
neu_req_node_setting_t *node_setting = data;
|
||||
json_req.node_setting.node = node_setting->node;
|
||||
json_req.node_setting.setting = node_setting->setting;
|
||||
*topic_p = plugin->config->node_setting_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_node_setting_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_GROUP_EVENT: {
|
||||
neu_req_add_group_t *add_grp = data;
|
||||
json_req.add_grp.node = add_grp->driver;
|
||||
json_req.add_grp.group = add_grp->group;
|
||||
json_req.add_grp.interval = add_grp->interval;
|
||||
*topic_p = plugin->config->group_add_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_add_group_config_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_DEL_GROUP_EVENT: {
|
||||
neu_req_del_group_t *del_grp = data;
|
||||
json_req.del_grp.node = del_grp->driver;
|
||||
json_req.del_grp.group = del_grp->group;
|
||||
*topic_p = plugin->config->group_del_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_del_group_config_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_UPDATE_GROUP_EVENT: {
|
||||
neu_req_update_group_t *update_grp = data;
|
||||
json_req.update_grp.node = update_grp->driver;
|
||||
json_req.update_grp.group = update_grp->group;
|
||||
json_req.update_grp.new_name = update_grp->new_name;
|
||||
json_req.update_grp.set_interval =
|
||||
update_grp->interval >= NEU_GROUP_INTERVAL_LIMIT;
|
||||
json_req.update_grp.interval = update_grp->interval;
|
||||
*topic_p = plugin->config->group_update_topic;
|
||||
neu_json_encode_by_fn(
|
||||
&json_req, neu_json_encode_update_group_config_req, &json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_TAG_EVENT:
|
||||
case NEU_REQ_UPDATE_TAG_EVENT: {
|
||||
neu_req_add_tag_t *add_tag = data;
|
||||
json_req.add_tags.node = add_tag->driver;
|
||||
json_req.add_tags.group = add_tag->group;
|
||||
json_req.add_tags.n_tag = add_tag->n_tag;
|
||||
json_req.add_tags.tags =
|
||||
calloc(add_tag->n_tag, sizeof(*json_req.add_tags.tags));
|
||||
if (NULL == json_req.add_tags.tags) {
|
||||
plog_error(plugin, "calloc fail");
|
||||
break;
|
||||
}
|
||||
for (uint16_t i = 0; i < add_tag->n_tag; ++i) {
|
||||
json_req.add_tags.tags[i].type = add_tag->tags[i].type;
|
||||
json_req.add_tags.tags[i].name = add_tag->tags[i].name;
|
||||
json_req.add_tags.tags[i].attribute = add_tag->tags[i].attribute;
|
||||
json_req.add_tags.tags[i].address = add_tag->tags[i].address;
|
||||
json_req.add_tags.tags[i].decimal = add_tag->tags[i].decimal;
|
||||
json_req.add_tags.tags[i].precision = add_tag->tags[i].precision;
|
||||
json_req.add_tags.tags[i].description =
|
||||
add_tag->tags[i].description;
|
||||
json_req.add_tags.tags[i].t = NEU_JSON_UNDEFINE;
|
||||
}
|
||||
*topic_p = NEU_REQ_ADD_TAG_EVENT == event
|
||||
? plugin->config->tag_add_topic
|
||||
: plugin->config->tag_update_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_add_tags_req,
|
||||
&json_str);
|
||||
|
||||
free(json_req.add_tags.tags);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_DEL_TAG_EVENT: {
|
||||
neu_req_del_tag_t *del_tag = data;
|
||||
json_req.del_tags.node = del_tag->driver;
|
||||
json_req.del_tags.group = del_tag->group;
|
||||
json_req.del_tags.n_tags = del_tag->n_tag;
|
||||
json_req.del_tags.tags =
|
||||
calloc(del_tag->n_tag, sizeof(*json_req.del_tags.tags));
|
||||
if (NULL == json_req.del_tags.tags) {
|
||||
plog_error(plugin, "calloc fail");
|
||||
break;
|
||||
}
|
||||
for (uint16_t i = 0; i < del_tag->n_tag; ++i) {
|
||||
json_req.del_tags.tags[i] = del_tag->tags[i];
|
||||
}
|
||||
*topic_p = plugin->config->tag_del_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_del_tags_req,
|
||||
&json_str);
|
||||
|
||||
free(json_req.del_tags.tags);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_GTAG_EVENT: {
|
||||
neu_req_add_gtag_t *add_gtag = data;
|
||||
json_req.add_gtag.node = add_gtag->driver;
|
||||
json_req.add_gtag.n_group = add_gtag->n_group;
|
||||
json_req.add_gtag.groups =
|
||||
calloc(add_gtag->n_group, sizeof(*json_req.add_gtag.groups));
|
||||
for (u_int16_t i = 0; i < add_gtag->n_group; i++) {
|
||||
json_req.add_gtag.groups[i].group =
|
||||
strdup(add_gtag->groups[i].group);
|
||||
json_req.add_gtag.groups[i].n_tag = add_gtag->groups[i].n_tag;
|
||||
json_req.add_gtag.groups[i].interval = add_gtag->groups[i].interval;
|
||||
json_req.add_gtag.groups[i].tags =
|
||||
calloc(add_gtag->groups[i].n_tag,
|
||||
sizeof(*json_req.add_gtag.groups->tags));
|
||||
for (u_int16_t j = 0; j < add_gtag->groups[i].n_tag; j++) {
|
||||
json_req.add_gtag.groups[i].tags[j].type =
|
||||
add_gtag->groups[i].tags[j].type;
|
||||
json_req.add_gtag.groups[i].tags[j].name =
|
||||
add_gtag->groups[i].tags[j].name;
|
||||
json_req.add_gtag.groups[i].tags[j].attribute =
|
||||
add_gtag->groups[i].tags[j].attribute;
|
||||
json_req.add_gtag.groups[i].tags[j].address =
|
||||
add_gtag->groups[i].tags[j].address;
|
||||
json_req.add_gtag.groups[i].tags[j].decimal =
|
||||
add_gtag->groups[i].tags[j].decimal;
|
||||
json_req.add_gtag.groups[i].tags[j].precision =
|
||||
add_gtag->groups[i].tags[j].precision;
|
||||
json_req.add_gtag.groups[i].tags[j].description =
|
||||
add_gtag->groups[i].tags[j].description;
|
||||
}
|
||||
}
|
||||
*topic_p = plugin->config->gtag_add_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_add_gtags_req,
|
||||
&json_str);
|
||||
|
||||
free(json_req.add_tags.tags);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_PLUGIN_EVENT: {
|
||||
neu_req_add_plugin_t *add_plugin = data;
|
||||
json_req.add_plugin.library = add_plugin->library;
|
||||
json_req.add_plugin.schema_file = add_plugin->schema_file;
|
||||
json_req.add_plugin.so_file = add_plugin->so_file;
|
||||
*topic_p = plugin->config->plugin_add_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_add_plugin_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_DEL_PLUGIN_EVENT: {
|
||||
neu_req_del_plugin_t *del_plugin = data;
|
||||
json_req.del_plugin.plugin = del_plugin->plugin;
|
||||
*topic_p = plugin->config->plugin_del_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_del_plugin_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT: {
|
||||
neu_req_subscribe_t *subscribe_grp = data;
|
||||
json_req.sub_grp.group = subscribe_grp->group;
|
||||
json_req.sub_grp.app = subscribe_grp->app;
|
||||
json_req.sub_grp.driver = subscribe_grp->driver;
|
||||
json_req.sub_grp.params = subscribe_grp->params;
|
||||
*topic_p = NEU_REQ_SUBSCRIBE_GROUP_EVENT == event
|
||||
? plugin->config->group_subscribe_topic
|
||||
: plugin->config->group_update_subscribe_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_subscribe_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_UNSUBSCRIBE_GROUP_EVENT: {
|
||||
neu_req_unsubscribe_t *unsubscribe_grp = data;
|
||||
json_req.unsub_grp.group = unsubscribe_grp->group;
|
||||
json_req.unsub_grp.app = unsubscribe_grp->app;
|
||||
json_req.unsub_grp.driver = unsubscribe_grp->driver;
|
||||
*topic_p = plugin->config->group_unsubscribe_topic;
|
||||
neu_json_encode_by_fn(&json_req, neu_json_encode_unsubscribe_req,
|
||||
&json_str);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_SUBSCRIBE_GROUPS_EVENT: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
plog_error(plugin, "unsupported event:%s",
|
||||
neu_reqresp_type_string(event));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return json_str;
|
||||
}
|
||||
|
||||
static void publish_cb(int errcode, neu_mqtt_qos_e qos, char *topic,
|
||||
uint8_t *payload, uint32_t len, void *data)
|
||||
{
|
||||
(void) qos;
|
||||
(void) topic;
|
||||
(void) len;
|
||||
|
||||
neu_plugin_t *plugin = data;
|
||||
|
||||
neu_adapter_update_metric_cb_t update_metric =
|
||||
plugin->common.adapter_callbacks->update_metric;
|
||||
|
||||
if (0 == errcode) {
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_SEND_MSGS_TOTAL, 1,
|
||||
NULL);
|
||||
} else {
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_SEND_MSG_ERRORS_TOTAL,
|
||||
1, NULL);
|
||||
}
|
||||
|
||||
free(payload);
|
||||
}
|
||||
|
||||
static inline int publish(neu_plugin_t *plugin, neu_mqtt_qos_e qos, char *topic,
|
||||
char *payload, size_t payload_len)
|
||||
{
|
||||
neu_adapter_update_metric_cb_t update_metric =
|
||||
plugin->common.adapter_callbacks->update_metric;
|
||||
|
||||
int rv = neu_mqtt_client_publish(
|
||||
plugin->mqtt_client, qos, topic, (uint8_t *) payload,
|
||||
(uint32_t) payload_len, plugin, publish_cb);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "pub [%s, QoS%d] fail", topic, qos);
|
||||
update_metric(plugin->common.adapter, NEU_METRIC_SEND_MSG_ERRORS_TOTAL,
|
||||
1, NULL);
|
||||
free(payload);
|
||||
rv = NEU_ERR_MQTT_PUBLISH_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int handle_nodes_state(neu_plugin_t *plugin, neu_reqresp_nodes_state_t *states)
|
||||
{
|
||||
int rv = 0;
|
||||
char *json_str = NULL;
|
||||
|
||||
if (NULL == plugin->mqtt_client) {
|
||||
rv = NEU_ERR_MQTT_IS_NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!neu_mqtt_client_is_connected(plugin->mqtt_client)) {
|
||||
// cache disable and we are disconnected
|
||||
rv = NEU_ERR_MQTT_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
json_str = generate_heartbeat_json(plugin, states->states);
|
||||
if (NULL == json_str) {
|
||||
plog_error(plugin, "generate heartbeat json fail");
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
char * topic = plugin->config->heartbeat_topic;
|
||||
neu_mqtt_qos_e qos = NEU_MQTT_QOS0;
|
||||
rv = publish(plugin, qos, topic, json_str, strlen(json_str));
|
||||
json_str = NULL;
|
||||
|
||||
end:
|
||||
utarray_free(states->states);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int handle_events(neu_plugin_t *plugin, neu_reqresp_type_e event, void *data)
|
||||
{
|
||||
int rv = 0;
|
||||
char *json_str = NULL;
|
||||
char *topic = NULL;
|
||||
|
||||
if (NULL == plugin->mqtt_client) {
|
||||
rv = NEU_ERR_MQTT_IS_NULL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!neu_mqtt_client_is_connected(plugin->mqtt_client)) {
|
||||
// cache disable and we are disconnected
|
||||
rv = NEU_ERR_MQTT_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
json_str = generate_event_json(plugin, event, data, &topic);
|
||||
if (NULL == json_str) {
|
||||
plog_error(plugin, "generate event:%s json fail",
|
||||
neu_reqresp_type_string(event));
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
neu_mqtt_qos_e qos = NEU_MQTT_QOS0;
|
||||
rv = publish(plugin, qos, topic, json_str, strlen(json_str));
|
||||
json_str = NULL;
|
||||
|
||||
end:
|
||||
switch (event) {
|
||||
case NEU_REQ_NODE_SETTING_EVENT:
|
||||
neu_req_node_setting_fini(data);
|
||||
break;
|
||||
case NEU_REQ_ADD_TAG_EVENT:
|
||||
case NEU_REQ_UPDATE_TAG_EVENT:
|
||||
neu_req_add_tag_fini(data);
|
||||
break;
|
||||
case NEU_REQ_DEL_TAG_EVENT:
|
||||
neu_req_del_tag_fini(data);
|
||||
break;
|
||||
case NEU_REQ_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT:
|
||||
break;
|
||||
case NEU_REQ_SUBSCRIBE_GROUPS_EVENT:
|
||||
neu_req_subscribe_groups_fini(data);
|
||||
break;
|
||||
case NEU_REQ_ADD_GTAG_EVENT: {
|
||||
neu_req_add_gtag_t *add_gtag = data;
|
||||
for (int i = 0; i < add_gtag->n_group; i++) {
|
||||
for (int j = 0; j < add_gtag->groups[i].n_tag; j++) {
|
||||
neu_tag_fini(&add_gtag->groups[i].tags[j]);
|
||||
}
|
||||
free(add_gtag->groups[i].tags);
|
||||
}
|
||||
free(add_gtag->groups);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#ifndef NEURON_PLUGIN_MONITOR_MQTT_HANDLE_H
|
||||
#define NEURON_PLUGIN_MONITOR_MQTT_HANDLE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "neuron.h"
|
||||
|
||||
int handle_nodes_state(neu_plugin_t *plugin, neu_reqresp_nodes_state_t *states);
|
||||
|
||||
int handle_events(neu_plugin_t *plugin, neu_reqresp_type_e event, void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -62,7 +62,7 @@ static int start_hearbeat_timer(neu_plugin_t *plugin, uint64_t interval)
|
||||
}
|
||||
|
||||
if (NULL == plugin->events) {
|
||||
plugin->events = neu_event_new();
|
||||
plugin->events = neu_event_new(plugin->common.name);
|
||||
if (NULL == plugin->events) {
|
||||
plog_error(plugin, "neu_event_new fail");
|
||||
return NEU_ERR_EINTERNAL;
|
||||
|
||||
@@ -44,6 +44,8 @@ void handle_add_adapter(nng_aio *aio)
|
||||
aio, neu_json_add_node_req_t, neu_json_decode_add_node_req, {
|
||||
if (strlen(req->name) >= NEU_NODE_NAME_LEN) {
|
||||
CHECK_NODE_NAME_LENGTH_ERR;
|
||||
} else if (strcmp(req->name, "monitor") == 0) {
|
||||
CHECK_NODE_MONITOR_ERR;
|
||||
} else {
|
||||
int ret = 0;
|
||||
neu_reqresp_head_t header = { 0 };
|
||||
@@ -84,6 +86,11 @@ static inline int send_node_update_req(nng_aio * aio,
|
||||
return NEU_ERR_NODE_NAME_EMPTY;
|
||||
}
|
||||
|
||||
if (strcmp(req->new_name, "monitor") == 0 ||
|
||||
strcmp(req->name, "monitor") == 0) {
|
||||
return NEU_ERR_NODE_NOT_ALLOW_UPDATE;
|
||||
}
|
||||
|
||||
neu_req_update_node_t cmd = { 0 };
|
||||
strcpy(cmd.node, req->name);
|
||||
strcpy(cmd.new_name, req->new_name);
|
||||
@@ -145,6 +152,7 @@ void handle_get_adapter(nng_aio *aio)
|
||||
int ret = 0;
|
||||
char plugin_name[NEU_PLUGIN_NAME_LEN] = { 0 };
|
||||
char node_name[NEU_NODE_NAME_LEN] = { 0 };
|
||||
char group_name[NEU_GROUP_NAME_LEN] = { 0 };
|
||||
|
||||
neu_plugin_t * plugin = neu_rest_get_plugin();
|
||||
neu_node_type_e node_type = { 0 };
|
||||
@@ -173,6 +181,33 @@ void handle_get_adapter(nng_aio *aio)
|
||||
strcpy(cmd.node, node_name);
|
||||
}
|
||||
|
||||
if (neu_http_get_param_str(aio, "group", group_name, sizeof(group_name)) >
|
||||
0) {
|
||||
strcpy(cmd.query.q_group_name, group_name);
|
||||
}
|
||||
|
||||
uintmax_t query_state = 0;
|
||||
if (neu_http_get_param_uintmax(aio, "state", &query_state) == 0) {
|
||||
if (query_state == 1 || query_state == 2 || query_state == 3 ||
|
||||
query_state == 4) {
|
||||
cmd.query.q_state = true;
|
||||
cmd.query.state = (int) query_state;
|
||||
}
|
||||
}
|
||||
|
||||
uintmax_t query_link = 0;
|
||||
if (neu_http_get_param_uintmax(aio, "link", &query_link) == 0) {
|
||||
if (query_link == 0 || query_link == 1) {
|
||||
cmd.query.q_link = true;
|
||||
cmd.query.link = (int) query_link;
|
||||
}
|
||||
}
|
||||
|
||||
uintmax_t sort_delay = 0;
|
||||
if (neu_http_get_param_uintmax(aio, "delay", &sort_delay) == 0) {
|
||||
cmd.query.s_delay = true;
|
||||
}
|
||||
|
||||
cmd.type = node_type;
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
|
||||
@@ -120,9 +120,7 @@ static int add_setting(context_t *ctx, neu_json_node_setting_req_t *data);
|
||||
|
||||
static inline bool is_static_node(const char *name, const char *plugin)
|
||||
{
|
||||
(void) name;
|
||||
(void) plugin;
|
||||
return false;
|
||||
return 0 == strcmp("monitor", name) && 0 == strcmp("Monitor", plugin);
|
||||
}
|
||||
|
||||
static context_t *context_new(nng_aio *aio, context_type_e t)
|
||||
|
||||
@@ -160,11 +160,12 @@ void handle_del_group_config(nng_aio *aio)
|
||||
|
||||
void handle_get_group_config(nng_aio *aio)
|
||||
{
|
||||
neu_plugin_t * plugin = neu_rest_get_plugin();
|
||||
char node_name[NEU_NODE_NAME_LEN] = { 0 };
|
||||
int ret = 0;
|
||||
neu_req_get_group_t cmd = { 0 };
|
||||
neu_reqresp_head_t header = {
|
||||
neu_plugin_t * plugin = neu_rest_get_plugin();
|
||||
char node_name[NEU_NODE_NAME_LEN] = { 0 };
|
||||
char group_name[NEU_GROUP_NAME_LEN] = { 0 };
|
||||
int ret = 0;
|
||||
neu_req_get_group_t cmd = { 0 };
|
||||
neu_reqresp_head_t header = {
|
||||
.ctx = aio,
|
||||
.type = NEU_REQ_GET_GROUP,
|
||||
.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM,
|
||||
@@ -178,6 +179,11 @@ void handle_get_group_config(nng_aio *aio)
|
||||
header.type = NEU_REQ_GET_DRIVER_GROUP;
|
||||
}
|
||||
|
||||
if (neu_http_get_param_str(aio, "group", group_name, sizeof(group_name)) >
|
||||
0) {
|
||||
strcpy(cmd.q_group, group_name);
|
||||
}
|
||||
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
|
||||
@@ -400,10 +406,16 @@ void handle_grp_subscribes(nng_aio *aio)
|
||||
NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT(
|
||||
aio, neu_json_subscribe_groups_req_t,
|
||||
neu_json_decode_subscribe_groups_req, {
|
||||
int ret = send_subscribe_groups(aio, req);
|
||||
if (0 != ret) {
|
||||
int ret = 0;
|
||||
if (req->n_group == 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(
|
||||
ret, { neu_http_response(aio, ret, result_error); });
|
||||
} else {
|
||||
ret = send_subscribe_groups(aio, req);
|
||||
if (0 != ret) {
|
||||
NEU_JSON_RESPONSE_ERROR(
|
||||
ret, { neu_http_response(aio, ret, result_error); });
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -482,4 +494,111 @@ void handle_grp_get_subscribe_resp(nng_aio * aio,
|
||||
free(result);
|
||||
free(sub_grp_configs.groups);
|
||||
utarray_free(groups->groups);
|
||||
}
|
||||
|
||||
void handle_grp_get_subscribes(nng_aio *aio)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_plugin_t * plugin = neu_rest_get_plugin();
|
||||
neu_req_get_driver_subscribe_group_t cmd = { 0 };
|
||||
neu_reqresp_head_t header = {
|
||||
.ctx = aio,
|
||||
.type = NEU_REQ_GET_DRIVER_SUBSCRIBE_GROUP,
|
||||
.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM,
|
||||
};
|
||||
|
||||
NEU_VALIDATE_JWT(aio);
|
||||
|
||||
// required parameter
|
||||
ret = neu_http_get_param_str(aio, "app", cmd.app, sizeof(cmd.app));
|
||||
if (ret <= 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
// optional parameter
|
||||
ret = neu_http_get_param_str(aio, "name", cmd.name, sizeof(cmd.name));
|
||||
if (-1 == ret || (size_t) ret == sizeof(cmd.name)) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void handle_grp_get_subscribes_resp(nng_aio * aio,
|
||||
neu_resp_get_subscribe_group_t *drivers)
|
||||
{
|
||||
char * result = NULL;
|
||||
neu_json_get_driver_subscribe_resp_t drivers_resp = { 0 };
|
||||
|
||||
utarray_foreach(drivers->groups, neu_resp_driver_subscribe_info_t *, group)
|
||||
{
|
||||
// int index = utarray_eltidx(drivers->groups, group);
|
||||
bool found = false;
|
||||
|
||||
for (int k = 0; k < drivers_resp.n_driver; k++) {
|
||||
if (strcmp(drivers_resp.drivers[k].driver, group->driver) == 0) {
|
||||
found = true;
|
||||
drivers_resp.drivers[k].n_group++;
|
||||
drivers_resp.drivers[k].groups = realloc(
|
||||
drivers_resp.drivers[k].groups,
|
||||
drivers_resp.drivers[k].n_group *
|
||||
sizeof(neu_json_get_driver_subscribe_resp_group_t));
|
||||
drivers_resp.drivers[k]
|
||||
.groups[drivers_resp.drivers[k].n_group - 1]
|
||||
.group = strdup(group->group);
|
||||
drivers_resp.drivers[k]
|
||||
.groups[drivers_resp.drivers[k].n_group - 1]
|
||||
.subscribed = group->subscribed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
drivers_resp.n_driver++;
|
||||
drivers_resp.drivers = realloc(
|
||||
drivers_resp.drivers,
|
||||
drivers_resp.n_driver *
|
||||
sizeof(neu_json_get_driver_subscribe_resp_driver_t));
|
||||
|
||||
drivers_resp.drivers[drivers_resp.n_driver - 1].driver =
|
||||
strdup(group->driver);
|
||||
drivers_resp.drivers[drivers_resp.n_driver - 1].n_group = 1;
|
||||
drivers_resp.drivers[drivers_resp.n_driver - 1].groups =
|
||||
calloc(1, sizeof(neu_json_get_driver_subscribe_resp_group_t));
|
||||
|
||||
drivers_resp.drivers[drivers_resp.n_driver - 1].groups[0].group =
|
||||
strdup(group->group);
|
||||
drivers_resp.drivers[drivers_resp.n_driver - 1]
|
||||
.groups[0]
|
||||
.subscribed = group->subscribed;
|
||||
}
|
||||
}
|
||||
|
||||
neu_json_encode_by_fn(&drivers_resp,
|
||||
neu_json_encode_get_driver_subscribe_resp, &result);
|
||||
|
||||
neu_http_ok(aio, result);
|
||||
free(result);
|
||||
|
||||
for (int i = 0; i < drivers_resp.n_driver; i++) {
|
||||
free(drivers_resp.drivers[i].driver);
|
||||
for (int j = 0; j < drivers_resp.drivers[i].n_group; j++) {
|
||||
free(drivers_resp.drivers[i].groups[j].group);
|
||||
}
|
||||
free(drivers_resp.drivers[i].groups);
|
||||
}
|
||||
free(drivers_resp.drivers);
|
||||
|
||||
utarray_free(drivers->groups);
|
||||
}
|
||||
@@ -39,4 +39,8 @@ void handle_grp_get_subscribe(nng_aio *aio);
|
||||
void handle_grp_get_subscribe_resp(nng_aio * aio,
|
||||
neu_resp_get_subscribe_group_t *groups);
|
||||
|
||||
void handle_grp_get_subscribes(nng_aio *aio);
|
||||
void handle_grp_get_subscribes_resp(nng_aio * aio,
|
||||
neu_resp_get_subscribe_group_t *groups);
|
||||
|
||||
#endif
|
||||
@@ -148,6 +148,9 @@ static struct neu_http_handler cors_handler[] = {
|
||||
{
|
||||
.url = "/api/v2/users",
|
||||
},
|
||||
{
|
||||
.url = "/api/v2/export/db",
|
||||
},
|
||||
};
|
||||
|
||||
static struct neu_http_handler rest_handlers[] = {
|
||||
@@ -350,6 +353,12 @@ static struct neu_http_handler rest_handlers[] = {
|
||||
.url = "/api/v2/subscribe",
|
||||
.value.handler = handle_grp_get_subscribe,
|
||||
},
|
||||
{
|
||||
.method = NEU_HTTP_METHOD_GET,
|
||||
.type = NEU_HTTP_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/subscribes",
|
||||
.value.handler = handle_grp_get_subscribes,
|
||||
},
|
||||
{
|
||||
.method = NEU_HTTP_METHOD_POST,
|
||||
.type = NEU_HTTP_HANDLER_FUNCTION,
|
||||
@@ -494,6 +503,12 @@ static struct neu_http_handler rest_handlers[] = {
|
||||
.url = "/api/v2/users",
|
||||
.value.handler = handle_delete_user,
|
||||
},
|
||||
{
|
||||
.method = NEU_HTTP_METHOD_GET,
|
||||
.type = NEU_HTTP_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/export/db",
|
||||
.value.handler = handle_export_db,
|
||||
},
|
||||
};
|
||||
|
||||
void neu_rest_handler(const struct neu_http_handler **handlers, uint32_t *size)
|
||||
|
||||
@@ -118,8 +118,8 @@ static int response(nng_aio *aio, char *content, enum nng_http_status status)
|
||||
nng_http_res_set_status(res, status);
|
||||
|
||||
nng_http_req *nng_req = nng_aio_get_input(aio, 0);
|
||||
nlog_info("%s %s [%d]", nng_http_req_get_method(nng_req),
|
||||
nng_http_req_get_uri(nng_req), status);
|
||||
nlog_notice("%s %s [%d]", nng_http_req_get_method(nng_req),
|
||||
nng_http_req_get_uri(nng_req), status);
|
||||
|
||||
nng_aio_set_output(aio, 0, res);
|
||||
nng_aio_finish(aio, 0);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -35,6 +36,7 @@
|
||||
|
||||
#include "argparse.h"
|
||||
#include "parser/neu_json_login.h"
|
||||
#include "persist/persist_impl.h"
|
||||
#include "json/neu_json_fn.h"
|
||||
|
||||
#include "handle.h"
|
||||
@@ -459,6 +461,10 @@ static struct {
|
||||
.plugin = "Modbus TCP",
|
||||
.schema = "modbus-tcp",
|
||||
},
|
||||
{
|
||||
.plugin = "Monitor",
|
||||
.schema = "monitor",
|
||||
},
|
||||
{
|
||||
.plugin = "MQTT",
|
||||
.schema = "mqtt",
|
||||
@@ -626,3 +632,314 @@ void handle_status(nng_aio *aio)
|
||||
neu_http_response(aio, 0, result);
|
||||
free(result);
|
||||
}
|
||||
|
||||
int nodes_write_to_csv(const char *filename, UT_array *nodes)
|
||||
{
|
||||
FILE *f = fopen(filename, "a");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
utarray_foreach(nodes, neu_persist_node_info_t *, node)
|
||||
{
|
||||
fprintf(f, "%s,%d,%d,%s\n", node->name, node->type, node->state,
|
||||
node->plugin_name);
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int settings_write_to_csv(const char *filename, const char *node_name,
|
||||
const char *settings)
|
||||
{
|
||||
FILE *f = fopen(filename, "a");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(f, "%s,%s\n", node_name, settings);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int groups_write_to_csv(const char *filename, const char *driver_name,
|
||||
UT_array *groups)
|
||||
{
|
||||
FILE *f = fopen(filename, "a");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
utarray_foreach(groups, neu_persist_group_info_t *, group)
|
||||
{
|
||||
fprintf(f, "%s,%s,%d, NULL\n", driver_name, group->name,
|
||||
group->interval);
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int subscribes_write_to_csv(const char *filename, const char *app_name,
|
||||
UT_array *subscribers)
|
||||
{
|
||||
FILE *f = fopen(filename, "a");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
utarray_foreach(subscribers, neu_persist_subscription_info_t *, sub)
|
||||
{
|
||||
fprintf(f, "%s,%s,%s,%s,%s\n", app_name, sub->driver_name,
|
||||
sub->group_name, sub->params, sub->static_tags);
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tags_write_to_csv(const char *filename, const char *node_name,
|
||||
const char *group_name, UT_array *tags)
|
||||
{
|
||||
FILE *f = fopen(filename, "a");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
utarray_foreach(tags, neu_datatag_t *, tag)
|
||||
{
|
||||
fprintf(f, "%s,%s,%s,%s,%d,%d,%f,%f,%d,%s,%s,NULL\n", node_name,
|
||||
group_name, tag->name, tag->address, tag->attribute,
|
||||
tag->precision, tag->decimal, tag->bias, tag->type,
|
||||
tag->description, tag->format);
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int write_csv_header()
|
||||
{
|
||||
FILE *f = fopen("nodes.csv", "w");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", "nodes.csv");
|
||||
return -1;
|
||||
}
|
||||
fprintf(f, "name,type,state,plugin_name\n");
|
||||
fclose(f);
|
||||
|
||||
f = fopen("settings.csv", "w");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", "settings.csv");
|
||||
return -1;
|
||||
}
|
||||
fprintf(f, "node_name,setting\n");
|
||||
fclose(f);
|
||||
|
||||
f = fopen("groups.csv", "w");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", "groups.csv");
|
||||
return -1;
|
||||
}
|
||||
fprintf(f, "driver_name,name,interval,context\n");
|
||||
fclose(f);
|
||||
|
||||
f = fopen("tags.csv", "w");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", "tags.csv");
|
||||
return -1;
|
||||
}
|
||||
fprintf(f,
|
||||
"driver_name,group_name,name,address,attribute,precision,"
|
||||
"decimal,bias,type,description,format,value\n");
|
||||
fclose(f);
|
||||
|
||||
f = fopen("subscribes.csv", "w");
|
||||
if (NULL == f) {
|
||||
nlog_error("failed to open file:%s", "subscribes.csv");
|
||||
return -1;
|
||||
}
|
||||
fprintf(f, "app_name,driver_name,group_name,params,static_tags\n");
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read_file(const char *file_name, void **datap, size_t *lenp)
|
||||
{
|
||||
int rv = 0;
|
||||
FILE * f;
|
||||
struct stat st;
|
||||
size_t len;
|
||||
void * data;
|
||||
|
||||
if (stat(file_name, &st) != 0) {
|
||||
return NEU_ERR_FILE_NOT_EXIST;
|
||||
}
|
||||
|
||||
if ((f = fopen(file_name, "rb")) == NULL) {
|
||||
nlog_error("open fail: %s", file_name);
|
||||
return NEU_ERR_FILE_OPEN_FAILURE;
|
||||
}
|
||||
|
||||
len = st.st_size;
|
||||
if (len > 0) {
|
||||
if ((data = malloc(len)) == NULL) {
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
goto done;
|
||||
}
|
||||
if (fread(data, 1, len, f) != len) {
|
||||
nlog_error("file read failued, errno = %d", errno);
|
||||
rv = NEU_ERR_FILE_READ_FAILURE;
|
||||
free(data);
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
*datap = data;
|
||||
*lenp = len;
|
||||
done:
|
||||
fclose(f);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
void handle_export_db(nng_aio *aio)
|
||||
{
|
||||
write_csv_header();
|
||||
|
||||
UT_array *nodes = NULL;
|
||||
int rv = neu_persister_load_nodes(&nodes);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
rv = nodes_write_to_csv("nodes.csv", nodes);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
return;
|
||||
}
|
||||
|
||||
utarray_foreach(nodes, neu_persist_node_info_t *, node)
|
||||
{
|
||||
char *settings = NULL;
|
||||
rv = neu_persister_load_node_setting(node->name,
|
||||
(const char **) &settings);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
return;
|
||||
}
|
||||
rv = settings_write_to_csv("settings.csv", node->name, settings);
|
||||
free(settings);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
utarray_foreach(nodes, neu_persist_node_info_t *, node)
|
||||
{
|
||||
if (node->type == 2) {
|
||||
UT_array *subscribers = NULL;
|
||||
rv = neu_persister_load_subscriptions(node->name, &subscribers);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
return;
|
||||
}
|
||||
rv = subscribes_write_to_csv("subscribes.csv", node->name,
|
||||
subscribers);
|
||||
utarray_free(subscribers);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
utarray_foreach(nodes, neu_persist_node_info_t *, node)
|
||||
{
|
||||
UT_array *groups = NULL;
|
||||
rv = neu_persister_load_groups(node->name, &groups);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
return;
|
||||
}
|
||||
rv = groups_write_to_csv("groups.csv", node->name, groups);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
return;
|
||||
}
|
||||
|
||||
utarray_foreach(groups, neu_persist_group_info_t *, group)
|
||||
{
|
||||
UT_array *tags = NULL;
|
||||
rv = neu_persister_load_tags(node->name, group->name, &tags);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
utarray_free(groups);
|
||||
return;
|
||||
}
|
||||
rv = tags_write_to_csv("tags.csv", node->name, group->name, tags);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_WRITE_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
utarray_free(nodes);
|
||||
utarray_free(groups);
|
||||
return;
|
||||
}
|
||||
utarray_free(tags);
|
||||
}
|
||||
utarray_free(groups);
|
||||
}
|
||||
|
||||
utarray_free(nodes);
|
||||
|
||||
system("rm -rf neuron.zip");
|
||||
system("zip neuron.zip nodes.csv settings.csv groups.csv tags.csv "
|
||||
"subscribes.csv");
|
||||
|
||||
void * data = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
rv = read_file("neuron.zip", &data, &len);
|
||||
if (rv != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_READ_FAILURE, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
neu_http_response_file(aio, data, len,
|
||||
"attachment; filename=\"neuron.zip\"");
|
||||
free(data);
|
||||
}
|
||||
|
||||
@@ -36,4 +36,6 @@ void handle_add_user(nng_aio *aio);
|
||||
void handle_update_user(nng_aio *aio);
|
||||
void handle_delete_user(nng_aio *aio);
|
||||
|
||||
void handle_export_db(nng_aio *aio);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -279,6 +279,13 @@ static int dashb_plugin_request(neu_plugin_t * plugin,
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_DRIVER_SUBSCRIBE_GROUP:
|
||||
handle_grp_get_subscribes_resp(header->ctx,
|
||||
(neu_resp_get_subscribe_group_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_NODE_SETTING:
|
||||
handle_get_node_setting_resp(header->ctx,
|
||||
(neu_resp_get_node_setting_t *) data);
|
||||
|
||||
@@ -147,7 +147,7 @@ int main(int argc, char *argv[])
|
||||
.params.tcp_server.stop_listen = stop_listen,
|
||||
};
|
||||
|
||||
events = neu_event_new();
|
||||
events = neu_event_new("modbus_simulator");
|
||||
conn = neu_conn_new(¶m, NULL, connected, disconnected);
|
||||
|
||||
signal(SIGINT, sig_handler);
|
||||
|
||||
@@ -267,7 +267,7 @@ int main(int argc, char *argv[])
|
||||
.params.tty_client.timeout = 3000,
|
||||
};
|
||||
|
||||
events = neu_event_new();
|
||||
events = neu_event_new("modbus_tty_simulator");
|
||||
conn = neu_conn_new(¶m, NULL, connected, disconnected);
|
||||
|
||||
neu_conn_start(conn);
|
||||
|
||||
+126
-21
@@ -63,6 +63,8 @@ static int adapter_update_metric(neu_adapter_t *adapter,
|
||||
const char *group);
|
||||
inline static void reply(neu_adapter_t *adapter, neu_reqresp_head_t *header,
|
||||
void *data);
|
||||
inline static void notify_monitor(neu_adapter_t * adapter,
|
||||
neu_reqresp_type_e event, void *data);
|
||||
|
||||
static const adapter_callbacks_t callback_funs = {
|
||||
.command = adapter_command,
|
||||
@@ -200,7 +202,7 @@ neu_adapter_t *neu_adapter_create(neu_adapter_info_t *info, bool load)
|
||||
}
|
||||
|
||||
adapter->name = strdup(info->name);
|
||||
adapter->events = neu_event_new();
|
||||
adapter->events = neu_event_new("adapter");
|
||||
adapter->state = NEU_NODE_RUNNING_STATE_INIT;
|
||||
adapter->handle = info->handle;
|
||||
adapter->cb_funs.command = callback_funs.command;
|
||||
@@ -695,13 +697,21 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
|
||||
switch (header->type) {
|
||||
case NEU_REQ_SUBSCRIBE_GROUP: {
|
||||
neu_req_subscribe_t *cmd = (neu_req_subscribe_t *) &header[1];
|
||||
neu_req_subscribe_t *cmd = (neu_req_subscribe_t *) &header[1];
|
||||
neu_resp_error_t error = { 0 };
|
||||
|
||||
if (adapter->module->type == NEU_NA_TYPE_DRIVER) {
|
||||
neu_adapter_driver_subscribe((neu_adapter_driver_t *) adapter, cmd);
|
||||
} else {
|
||||
adapter->module->intf_funs->request(
|
||||
adapter->plugin, (neu_reqresp_head_t *) header, &header[1]);
|
||||
error.error = NEU_ERR_GROUP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
if (error.error == NEU_ERR_SUCCESS && header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_SUBSCRIBE_GROUP_EVENT, cmd);
|
||||
}
|
||||
|
||||
neu_msg_free(msg);
|
||||
break;
|
||||
}
|
||||
@@ -727,6 +737,7 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_RESP_GET_NODE_SETTING:
|
||||
case NEU_REQ_UPDATE_GROUP:
|
||||
case NEU_RESP_GET_SUBSCRIBE_GROUP:
|
||||
case NEU_RESP_GET_DRIVER_SUBSCRIBE_GROUP:
|
||||
case NEU_RESP_ADD_TAG:
|
||||
case NEU_RESP_ADD_GTAG:
|
||||
case NEU_RESP_UPDATE_TAG:
|
||||
@@ -740,6 +751,23 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_RESP_PRGFILE_PROCESS:
|
||||
case NEU_RESP_CHECK_SCHEMA:
|
||||
case NEU_RESP_DRIVER_ACTION:
|
||||
case NEU_REQ_ADD_NODE_EVENT:
|
||||
case NEU_REQ_DEL_NODE_EVENT:
|
||||
case NEU_REQ_NODE_CTL_EVENT:
|
||||
case NEU_REQ_NODE_SETTING_EVENT:
|
||||
case NEU_REQ_ADD_GROUP_EVENT:
|
||||
case NEU_REQ_DEL_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_GROUP_EVENT:
|
||||
case NEU_REQ_ADD_TAG_EVENT:
|
||||
case NEU_REQ_DEL_TAG_EVENT:
|
||||
case NEU_REQ_UPDATE_TAG_EVENT:
|
||||
case NEU_REQ_ADD_GTAG_EVENT:
|
||||
case NEU_REQ_ADD_PLUGIN_EVENT:
|
||||
case NEU_REQ_DEL_PLUGIN_EVENT:
|
||||
case NEU_REQ_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UNSUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_SUBSCRIBE_GROUPS_EVENT:
|
||||
adapter->module->intf_funs->request(
|
||||
adapter->plugin, (neu_reqresp_head_t *) header, &header[1]);
|
||||
neu_msg_free(msg);
|
||||
@@ -989,7 +1017,12 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
error.error = neu_adapter_set_setting(adapter, cmd->setting);
|
||||
if (error.error == NEU_ERR_SUCCESS) {
|
||||
adapter_storage_setting(adapter->name, cmd->setting);
|
||||
free(cmd->setting);
|
||||
// ownership of `cmd->setting` transfer
|
||||
if (header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_NODE_SETTING_EVENT, cmd);
|
||||
} else {
|
||||
free(cmd->setting);
|
||||
}
|
||||
} else {
|
||||
free(cmd->setting);
|
||||
}
|
||||
@@ -1033,12 +1066,15 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_GET_GROUP: {
|
||||
|
||||
neu_req_get_group_t *cmd = (neu_req_get_group_t *) &header[1];
|
||||
|
||||
neu_msg_exchange(header);
|
||||
|
||||
if (adapter->module->type == NEU_NA_TYPE_DRIVER) {
|
||||
neu_resp_get_group_t resp = {
|
||||
.groups = neu_adapter_driver_get_group(
|
||||
(neu_adapter_driver_t *) adapter)
|
||||
(neu_adapter_driver_t *) adapter, cmd->q_group)
|
||||
};
|
||||
header->type = NEU_RESP_GET_GROUP;
|
||||
reply(adapter, header, &resp);
|
||||
@@ -1095,6 +1131,9 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
if (error.error == NEU_ERR_SUCCESS) {
|
||||
adapter_storage_add_group(adapter->name, cmd->group, cmd->interval,
|
||||
NULL);
|
||||
if (header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_ADD_GROUP_EVENT, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
neu_msg_exchange(header);
|
||||
@@ -1118,6 +1157,9 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
if (resp.error == NEU_ERR_SUCCESS) {
|
||||
adapter_storage_update_group(adapter->name, cmd->group,
|
||||
cmd->new_name, cmd->interval);
|
||||
if (header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_UPDATE_GROUP_EVENT, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(resp.driver, cmd->driver);
|
||||
@@ -1144,6 +1186,9 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
|
||||
if (error.error == NEU_ERR_SUCCESS) {
|
||||
adapter_storage_del_group(cmd->driver, cmd->group);
|
||||
if (header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_DEL_GROUP_EVENT, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
neu_msg_exchange(header);
|
||||
@@ -1164,6 +1209,10 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
break;
|
||||
}
|
||||
|
||||
if (0 == error.error && header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_NODE_CTL_EVENT, cmd);
|
||||
}
|
||||
|
||||
neu_msg_exchange(header);
|
||||
header->type = NEU_RESP_ERROR;
|
||||
reply(adapter, header, &error);
|
||||
@@ -1203,10 +1252,14 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
error.error = NEU_ERR_GROUP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < cmd->n_tag; i++) {
|
||||
free(cmd->tags[i]);
|
||||
if (0 == error.error && header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_DEL_TAG_EVENT, cmd);
|
||||
} else {
|
||||
for (uint16_t i = 0; i < cmd->n_tag; i++) {
|
||||
free(cmd->tags[i]);
|
||||
}
|
||||
free(cmd->tags);
|
||||
}
|
||||
free(cmd->tags);
|
||||
|
||||
neu_msg_exchange(header);
|
||||
header->type = NEU_RESP_ERROR;
|
||||
@@ -1256,25 +1309,33 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
}
|
||||
}
|
||||
|
||||
for (uint16_t i = resp.index; i < cmd->n_tag; i++) {
|
||||
neu_tag_fini(&cmd->tags[i]);
|
||||
}
|
||||
|
||||
if (resp.index) {
|
||||
// we have added some tags, try to persist
|
||||
adapter_storage_add_tags(cmd->driver, cmd->group, cmd->tags,
|
||||
resp.index);
|
||||
cmd->n_tag = resp.index;
|
||||
if (header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_ADD_TAG_EVENT, cmd);
|
||||
} else {
|
||||
neu_req_add_tag_fini(cmd);
|
||||
}
|
||||
} else {
|
||||
free(cmd->tags);
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < cmd->n_tag; i++) {
|
||||
neu_tag_fini(&cmd->tags[i]);
|
||||
}
|
||||
free(cmd->tags);
|
||||
|
||||
neu_msg_exchange(header);
|
||||
header->type = NEU_RESP_ADD_TAG;
|
||||
reply(adapter, header, &resp);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_GTAG: {
|
||||
neu_req_add_gtag_t *cmd = (neu_req_add_gtag_t *) &header[1];
|
||||
neu_resp_add_tag_t resp = { 0 };
|
||||
neu_req_add_gtag_t *cmd = (neu_req_add_gtag_t *) &header[1];
|
||||
neu_resp_add_tag_t resp = { 0 };
|
||||
int error = -1;
|
||||
|
||||
if (adapter->module->type != NEU_NA_TYPE_DRIVER) {
|
||||
resp.error = NEU_ERR_GROUP_NOT_ALLOW;
|
||||
@@ -1287,16 +1348,22 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
cmd->groups[i].tags,
|
||||
cmd->groups[i].n_tag);
|
||||
}
|
||||
if (header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_ADD_GTAG_EVENT, cmd);
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < cmd->n_group; i++) {
|
||||
for (int j = 0; j < cmd->groups[i].n_tag; j++) {
|
||||
neu_tag_fini(&cmd->groups[i].tags[j]);
|
||||
if (error != 0) {
|
||||
for (int i = 0; i < cmd->n_group; i++) {
|
||||
for (int j = 0; j < cmd->groups[i].n_tag; j++) {
|
||||
neu_tag_fini(&cmd->groups[i].tags[j]);
|
||||
}
|
||||
free(cmd->groups[i].tags);
|
||||
}
|
||||
free(cmd->groups[i].tags);
|
||||
free(cmd->groups);
|
||||
}
|
||||
free(cmd->groups);
|
||||
|
||||
neu_msg_exchange(header);
|
||||
header->type = NEU_RESP_ADD_GTAG;
|
||||
@@ -1335,10 +1402,19 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
resp.error = NEU_ERR_GROUP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < cmd->n_tag; i++) {
|
||||
for (uint16_t i = resp.index; i < cmd->n_tag; i++) {
|
||||
neu_tag_fini(&cmd->tags[i]);
|
||||
}
|
||||
free(cmd->tags);
|
||||
if (resp.index > 0) {
|
||||
cmd->n_tag = resp.index;
|
||||
if (header->monitor) {
|
||||
notify_monitor(adapter, NEU_REQ_UPDATE_TAG_EVENT, cmd);
|
||||
} else {
|
||||
neu_req_add_tag_fini(cmd);
|
||||
}
|
||||
} else {
|
||||
free(cmd->tags);
|
||||
}
|
||||
|
||||
neu_msg_exchange(header);
|
||||
header->type = NEU_RESP_UPDATE_TAG;
|
||||
@@ -1736,6 +1812,16 @@ neu_node_state_t neu_adapter_get_state(neu_adapter_t *adapter)
|
||||
return state;
|
||||
}
|
||||
|
||||
UT_array *neu_adapter_get_groups(neu_adapter_t *adapter, const char *filter)
|
||||
{
|
||||
if (adapter->module->type != NEU_NA_TYPE_DRIVER) {
|
||||
return NULL;
|
||||
} else {
|
||||
return neu_adapter_driver_get_group((neu_adapter_driver_t *) adapter,
|
||||
filter);
|
||||
}
|
||||
}
|
||||
|
||||
neu_event_timer_t *neu_adapter_add_timer(neu_adapter_t * adapter,
|
||||
neu_event_timer_param_t param)
|
||||
{
|
||||
@@ -1803,3 +1889,22 @@ inline static void reply(neu_adapter_t *adapter, neu_reqresp_head_t *header,
|
||||
strerror(errno), errno);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void notify_monitor(neu_adapter_t * adapter,
|
||||
neu_reqresp_type_e event, void *data)
|
||||
{
|
||||
neu_msg_t *msg = neu_msg_new(event, NULL, data);
|
||||
if (NULL == msg) {
|
||||
return;
|
||||
}
|
||||
neu_reqresp_head_t *header = neu_msg_get_header(msg);
|
||||
strcpy(header->receiver, "monitor");
|
||||
strncpy(header->sender, adapter->name, NEU_NODE_NAME_LEN);
|
||||
int ret = neu_send_msg(adapter->control_fd, msg);
|
||||
if (0 != ret) {
|
||||
nlog_warn("notify %s of %s, error: %s(%d)", header->receiver,
|
||||
neu_reqresp_type_string(header->type), strerror(errno),
|
||||
errno);
|
||||
neu_msg_free(msg);
|
||||
}
|
||||
}
|
||||
@@ -95,6 +95,7 @@ void neu_adapter_del_timer(neu_adapter_t *adapter, neu_event_timer_t *timer);
|
||||
int neu_adapter_set_setting(neu_adapter_t *adapter, const char *config);
|
||||
int neu_adapter_get_setting(neu_adapter_t *adapter, char **config);
|
||||
neu_node_state_t neu_adapter_get_state(neu_adapter_t *adapter);
|
||||
UT_array *neu_adapter_get_groups(neu_adapter_t *adapter, const char *filter);
|
||||
|
||||
static inline void neu_adapter_reset_metrics(neu_adapter_t *adapter)
|
||||
{
|
||||
|
||||
+43
-24
@@ -45,7 +45,8 @@ struct elem {
|
||||
neu_dvalue_t value;
|
||||
neu_dvalue_t value_old;
|
||||
|
||||
neu_tag_meta_t metas[NEU_TAG_META_SIZE];
|
||||
neu_tag_meta_t *metas;
|
||||
int n_meta;
|
||||
|
||||
tkey_t key;
|
||||
UT_hash_handle hh;
|
||||
@@ -115,6 +116,13 @@ void neu_driver_cache_destroy(neu_driver_cache_t *cache)
|
||||
free(elem->value.value.bools.bools);
|
||||
}
|
||||
|
||||
if (elem->metas != NULL) {
|
||||
for (int i = 0; i < elem->n_meta; i++) {
|
||||
neu_free_dvalue(&elem->metas[i].value);
|
||||
}
|
||||
free(elem->metas);
|
||||
}
|
||||
|
||||
free(elem);
|
||||
}
|
||||
|
||||
@@ -764,9 +772,16 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache,
|
||||
}
|
||||
elem->value.type = value.type;
|
||||
|
||||
memset(elem->metas, 0, sizeof(neu_tag_meta_t) * NEU_TAG_META_SIZE);
|
||||
for (int i = 0; i < n_meta; i++) {
|
||||
memcpy(&elem->metas[i], &metas[i], sizeof(neu_tag_meta_t));
|
||||
if (metas != NULL && n_meta != 0) {
|
||||
if (elem->metas != NULL) {
|
||||
free(elem->metas);
|
||||
}
|
||||
elem->metas = calloc(n_meta, sizeof(neu_tag_meta_t));
|
||||
for (int i = 0; i < n_meta; i++) {
|
||||
memcpy(&elem->metas[i], &metas[i], sizeof(neu_tag_meta_t));
|
||||
}
|
||||
|
||||
elem->n_meta = n_meta;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -784,7 +799,7 @@ void neu_driver_cache_update(neu_driver_cache_t *cache, const char *group,
|
||||
|
||||
int neu_driver_cache_meta_get(neu_driver_cache_t *cache, const char *group,
|
||||
const char *tag, neu_driver_cache_value_t *value,
|
||||
neu_tag_meta_t *metas, int n_meta)
|
||||
neu_tag_meta_t **metas, int *n_meta)
|
||||
{
|
||||
struct elem *elem = NULL;
|
||||
int ret = -1;
|
||||
@@ -798,8 +813,14 @@ int neu_driver_cache_meta_get(neu_driver_cache_t *cache, const char *group,
|
||||
value->value.type = elem->value.type;
|
||||
value->value.precision = elem->value.precision;
|
||||
|
||||
assert(n_meta <= NEU_TAG_META_SIZE);
|
||||
memcpy(metas, elem->metas, sizeof(neu_tag_meta_t) * NEU_TAG_META_SIZE);
|
||||
// assert(n_meta <= NEU_TAG_META_SIZE);
|
||||
if (elem->metas) {
|
||||
*metas = calloc(elem->n_meta, sizeof(neu_tag_meta_t));
|
||||
memcpy(*metas, elem->metas, sizeof(neu_tag_meta_t) * elem->n_meta);
|
||||
} else {
|
||||
*metas = NULL;
|
||||
}
|
||||
*n_meta = elem->n_meta;
|
||||
|
||||
switch (elem->value.type) {
|
||||
case NEU_TYPE_INT8:
|
||||
@@ -941,13 +962,6 @@ int neu_driver_cache_meta_get(neu_driver_cache_t *cache, const char *group,
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NEU_TAG_META_SIZE; i++) {
|
||||
if (strlen(elem->metas[i].name) > 0) {
|
||||
memcpy(&value->metas[i], &elem->metas[i],
|
||||
sizeof(neu_tag_meta_t));
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
@@ -959,7 +973,7 @@ int neu_driver_cache_meta_get(neu_driver_cache_t *cache, const char *group,
|
||||
int neu_driver_cache_meta_get_changed(neu_driver_cache_t *cache,
|
||||
const char *group, const char *tag,
|
||||
neu_driver_cache_value_t *value,
|
||||
neu_tag_meta_t *metas, int n_meta)
|
||||
neu_tag_meta_t **metas, int *n_meta)
|
||||
{
|
||||
struct elem *elem = NULL;
|
||||
int ret = -1;
|
||||
@@ -973,8 +987,14 @@ int neu_driver_cache_meta_get_changed(neu_driver_cache_t *cache,
|
||||
value->value.type = elem->value.type;
|
||||
value->value.precision = elem->value.precision;
|
||||
|
||||
assert(n_meta <= NEU_TAG_META_SIZE);
|
||||
memcpy(metas, elem->metas, sizeof(neu_tag_meta_t) * NEU_TAG_META_SIZE);
|
||||
// assert(n_meta <= NEU_TAG_META_SIZE);
|
||||
if (elem->metas) {
|
||||
*metas = calloc(elem->n_meta, sizeof(neu_tag_meta_t));
|
||||
memcpy(*metas, elem->metas, sizeof(neu_tag_meta_t) * elem->n_meta);
|
||||
} else {
|
||||
*metas = NULL;
|
||||
}
|
||||
*n_meta = elem->n_meta;
|
||||
|
||||
switch (elem->value.type) {
|
||||
case NEU_TYPE_INT8:
|
||||
@@ -1116,13 +1136,6 @@ int neu_driver_cache_meta_get_changed(neu_driver_cache_t *cache,
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NEU_TAG_META_SIZE; i++) {
|
||||
if (strlen(elem->metas[i].name) > 0) {
|
||||
memcpy(&value->metas[i], &elem->metas[i],
|
||||
sizeof(neu_tag_meta_t));
|
||||
}
|
||||
}
|
||||
|
||||
if (elem->value.type != NEU_TYPE_ERROR) {
|
||||
elem->changed = false;
|
||||
}
|
||||
@@ -1165,6 +1178,12 @@ void neu_driver_cache_del(neu_driver_cache_t *cache, const char *group,
|
||||
elem->value.type < NEU_TYPE_ARRAY_STRING) {
|
||||
free(elem->value.value.bools.bools);
|
||||
}
|
||||
if (elem->metas != NULL) {
|
||||
for (int i = 0; i < elem->n_meta; i++) {
|
||||
neu_free_dvalue(&elem->metas[i].value);
|
||||
}
|
||||
free(elem->metas);
|
||||
}
|
||||
free(elem);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,17 +50,16 @@ void neu_driver_cache_update_trace(neu_driver_cache_t *cache, const char *group,
|
||||
void *neu_driver_cache_get_trace(neu_driver_cache_t *cache, const char *group);
|
||||
|
||||
typedef struct {
|
||||
neu_dvalue_t value;
|
||||
int64_t timestamp;
|
||||
neu_tag_meta_t metas[NEU_TAG_META_SIZE];
|
||||
neu_dvalue_t value;
|
||||
int64_t timestamp;
|
||||
} neu_driver_cache_value_t;
|
||||
|
||||
int neu_driver_cache_meta_get(neu_driver_cache_t *cache, const char *group,
|
||||
const char *tag, neu_driver_cache_value_t *value,
|
||||
neu_tag_meta_t *metas, int n_meta);
|
||||
neu_tag_meta_t **metas, int *n_meta);
|
||||
int neu_driver_cache_meta_get_changed(neu_driver_cache_t *cache,
|
||||
const char *group, const char *tag,
|
||||
neu_driver_cache_value_t *value,
|
||||
neu_tag_meta_t *metas, int n_meta);
|
||||
neu_tag_meta_t **metas, int *n_meta);
|
||||
|
||||
#endif
|
||||
|
||||
+38
-15
@@ -375,6 +375,13 @@ static void update_im(neu_adapter_t *adapter, const char *group,
|
||||
} else {
|
||||
neu_free_dvalue(&tag_value->value);
|
||||
}
|
||||
|
||||
if (tag_value->metas != NULL) {
|
||||
for (int i = 0; i < tag_value->n_meta; i++) {
|
||||
neu_free_dvalue(&tag_value->metas[i].value);
|
||||
}
|
||||
free(tag_value->metas);
|
||||
}
|
||||
}
|
||||
utarray_free(data->tags);
|
||||
free(data->group);
|
||||
@@ -427,7 +434,7 @@ neu_adapter_driver_t *neu_adapter_driver_create()
|
||||
neu_adapter_driver_t *driver = calloc(1, sizeof(neu_adapter_driver_t));
|
||||
|
||||
driver->cache = neu_driver_cache_new();
|
||||
driver->driver_events = neu_event_new();
|
||||
driver->driver_events = neu_event_new("driver");
|
||||
driver->adapter.cb_funs.driver.update = update;
|
||||
driver->adapter.cb_funs.driver.write_response = write_response;
|
||||
driver->adapter.cb_funs.driver.update_im = update_im;
|
||||
@@ -1622,6 +1629,10 @@ int neu_adapter_driver_update_group(neu_adapter_driver_t *driver,
|
||||
if (NULL != new_name && 0 != strcmp(name, new_name)) {
|
||||
char *new_name_cp1 = strdup(new_name);
|
||||
char *new_name_cp2 = strdup(new_name);
|
||||
if (find->grp.group_free != NULL) {
|
||||
find->grp.group_free(&find->grp);
|
||||
find->grp.group_free = NULL;
|
||||
}
|
||||
if (new_name_cp1 && new_name_cp2 &&
|
||||
0 == neu_group_set_name(find->group, new_name)) {
|
||||
HASH_DEL(driver->groups, find);
|
||||
@@ -1757,7 +1768,8 @@ int neu_adapter_driver_group_exist(neu_adapter_driver_t *driver,
|
||||
return ret;
|
||||
}
|
||||
|
||||
UT_array *neu_adapter_driver_get_group(neu_adapter_driver_t *driver)
|
||||
UT_array *neu_adapter_driver_get_group(neu_adapter_driver_t *driver,
|
||||
const char * filter)
|
||||
{
|
||||
group_t * el = NULL, *tmp = NULL;
|
||||
UT_array *groups = NULL;
|
||||
@@ -1767,13 +1779,16 @@ UT_array *neu_adapter_driver_get_group(neu_adapter_driver_t *driver)
|
||||
|
||||
HASH_ITER(hh, driver->groups, el, tmp)
|
||||
{
|
||||
neu_resp_group_info_t info = { 0 };
|
||||
|
||||
info.interval = neu_group_get_interval(el->group);
|
||||
info.tag_count = neu_group_tag_size(el->group);
|
||||
strncpy(info.name, el->name, sizeof(info.name));
|
||||
if (strlen(filter) == 0 || strstr(el->name, filter) != NULL) {
|
||||
neu_resp_group_info_t info = { 0 };
|
||||
|
||||
utarray_push_back(groups, &info);
|
||||
info.interval = neu_group_get_interval(el->group);
|
||||
info.tag_count = neu_group_tag_size(el->group);
|
||||
strncpy(info.name, el->name, sizeof(info.name));
|
||||
|
||||
utarray_push_back(groups, &info);
|
||||
}
|
||||
}
|
||||
|
||||
return groups;
|
||||
@@ -2126,6 +2141,7 @@ static int report_callback(void *usr_data)
|
||||
data->driver = strdup(group->driver->adapter.name);
|
||||
data->group = strdup(group->name);
|
||||
utarray_new(data->tags, neu_resp_tag_value_meta_icd());
|
||||
utarray_reserve(data->tags, utarray_len(tags));
|
||||
|
||||
void *trace_ctx =
|
||||
neu_driver_cache_get_trace(group->driver->cache, group->name);
|
||||
@@ -2217,6 +2233,13 @@ static int report_callback(void *usr_data)
|
||||
} else {
|
||||
neu_free_dvalue(&tag_value->value);
|
||||
}
|
||||
|
||||
if (tag_value->metas != NULL) {
|
||||
for (int i = 0; i < tag_value->n_meta; i++) {
|
||||
neu_free_dvalue(&tag_value->metas[i].value);
|
||||
}
|
||||
free(tag_value->metas);
|
||||
}
|
||||
}
|
||||
utarray_free(data->tags);
|
||||
free(data->group);
|
||||
@@ -2421,15 +2444,15 @@ static void read_report_group(int64_t timestamp, int64_t timeout,
|
||||
|
||||
if (neu_tag_attribute_test(tag, NEU_ATTRIBUTE_SUBSCRIBE)) {
|
||||
if (neu_driver_cache_meta_get_changed(cache, group, tag->name,
|
||||
&value, tag_value.metas,
|
||||
NEU_TAG_META_SIZE) != 0) {
|
||||
&value, &tag_value.metas,
|
||||
&tag_value.n_meta) != 0) {
|
||||
nlog_debug("tag: %s not changed", tag->name);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (neu_driver_cache_meta_get(cache, group, tag->name, &value,
|
||||
tag_value.metas,
|
||||
NEU_TAG_META_SIZE) != 0) {
|
||||
&tag_value.metas,
|
||||
&tag_value.n_meta) != 0) {
|
||||
strcpy(tag_value.tag, tag->name);
|
||||
tag_value.value.type = NEU_TYPE_ERROR;
|
||||
tag_value.value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY;
|
||||
@@ -2616,8 +2639,8 @@ static void read_group(int64_t timestamp, int64_t timeout,
|
||||
tag_value.datatag.bias = tag->bias;
|
||||
|
||||
if (neu_driver_cache_meta_get(cache, group, tag->name, &value,
|
||||
tag_value.metas,
|
||||
NEU_TAG_META_SIZE) != 0) {
|
||||
&tag_value.metas,
|
||||
&tag_value.n_meta) != 0) {
|
||||
tag_value.value.type = NEU_TYPE_ERROR;
|
||||
tag_value.value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY;
|
||||
|
||||
@@ -2804,8 +2827,8 @@ static void read_group_paginate(int64_t timestamp, int64_t timeout,
|
||||
}
|
||||
|
||||
if (neu_driver_cache_meta_get(cache, group, tag->name, &value,
|
||||
tag_value.metas,
|
||||
NEU_TAG_META_SIZE) != 0) {
|
||||
&tag_value.metas,
|
||||
&tag_value.n_meta) != 0) {
|
||||
tag_value.value.type = NEU_TYPE_ERROR;
|
||||
tag_value.value.value.i32 = NEU_ERR_PLUGIN_TAG_NOT_READY;
|
||||
|
||||
|
||||
@@ -54,7 +54,8 @@ int neu_adapter_driver_del_group(neu_adapter_driver_t *driver,
|
||||
const char * name);
|
||||
int neu_adapter_driver_group_exist(neu_adapter_driver_t *driver,
|
||||
const char * name);
|
||||
UT_array *neu_adapter_driver_get_group(neu_adapter_driver_t *driver);
|
||||
UT_array *neu_adapter_driver_get_group(neu_adapter_driver_t *driver,
|
||||
const char * filter);
|
||||
uint16_t neu_adapter_driver_group_count(neu_adapter_driver_t *driver);
|
||||
uint16_t neu_adapter_driver_new_group_count(neu_adapter_driver_t *driver,
|
||||
neu_req_add_gtag_t * cmd);
|
||||
|
||||
+4
-3
@@ -18,6 +18,7 @@
|
||||
**/
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/sysinfo.h>
|
||||
@@ -45,7 +46,7 @@ static void find_os_info()
|
||||
FILE *f = popen(cmd, "r");
|
||||
|
||||
if (NULL == f) {
|
||||
nlog_error("popen command fail");
|
||||
nlog_error("popen command fail(%s)", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,7 +101,7 @@ static size_t parse_memory_fields(int col)
|
||||
|
||||
f = popen(buf, "r");
|
||||
if (NULL == f) {
|
||||
nlog_error("popen command fail");
|
||||
nlog_error("popen command fail(%s)", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -135,7 +136,7 @@ static inline size_t neuron_memory_used()
|
||||
|
||||
f = popen(buf, "r");
|
||||
if (NULL == f) {
|
||||
nlog_error("popen command fail");
|
||||
nlog_error("popen command fail(%s)", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+94
-74
@@ -30,80 +30,100 @@ extern "C" {
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
#define NEU_REQRESP_TYPE_MAP(XX) \
|
||||
XX(NEU_RESP_ERROR, neu_resp_error_t) \
|
||||
XX(NEU_REQ_READ_GROUP, neu_req_read_group_t) \
|
||||
XX(NEU_RESP_READ_GROUP, neu_resp_read_group_t) \
|
||||
XX(NEU_REQ_READ_GROUP_PAGINATE, neu_req_read_group_paginate_t) \
|
||||
XX(NEU_RESP_READ_GROUP_PAGINATE, neu_resp_read_group_paginate_t) \
|
||||
XX(NEU_REQ_TEST_READ_TAG, neu_req_test_read_tag_t) \
|
||||
XX(NEU_RESP_TEST_READ_TAG, neu_resp_test_read_tag_t) \
|
||||
XX(NEU_REQ_WRITE_TAG, neu_req_write_tag_t) \
|
||||
XX(NEU_REQ_WRITE_TAGS, neu_req_write_tags_t) \
|
||||
XX(NEU_REQ_WRITE_GTAGS, neu_req_write_gtags_t) \
|
||||
XX(NEU_REQ_SUBSCRIBE_GROUP, neu_req_subscribe_t) \
|
||||
XX(NEU_REQ_UNSUBSCRIBE_GROUP, neu_req_unsubscribe_t) \
|
||||
XX(NEU_REQ_UPDATE_SUBSCRIBE_GROUP, neu_req_subscribe_t) \
|
||||
XX(NEU_REQ_SUBSCRIBE_GROUPS, neu_req_subscribe_groups_t) \
|
||||
XX(NEU_REQ_GET_SUBSCRIBE_GROUP, neu_req_get_subscribe_group_t) \
|
||||
XX(NEU_RESP_GET_SUBSCRIBE_GROUP, neu_resp_get_subscribe_group_t) \
|
||||
XX(NEU_REQ_GET_SUB_DRIVER_TAGS, neu_req_get_sub_driver_tags_t) \
|
||||
XX(NEU_RESP_GET_SUB_DRIVER_TAGS, neu_resp_get_sub_driver_tags_t) \
|
||||
XX(NEU_REQ_NODE_INIT, neu_req_node_init_t) \
|
||||
XX(NEU_REQ_NODE_UNINIT, neu_req_node_uninit_t) \
|
||||
XX(NEU_RESP_NODE_UNINIT, neu_resp_node_uninit_t) \
|
||||
XX(NEU_REQ_ADD_NODE, neu_req_add_node_t) \
|
||||
XX(NEU_REQ_UPDATE_NODE, neu_req_update_node_t) \
|
||||
XX(NEU_REQ_DEL_NODE, neu_req_del_node_t) \
|
||||
XX(NEU_REQ_GET_NODE, neu_req_get_node_t) \
|
||||
XX(NEU_RESP_GET_NODE, neu_resp_get_node_t) \
|
||||
XX(NEU_REQ_NODE_SETTING, neu_req_node_setting_t) \
|
||||
XX(NEU_REQ_GET_NODE_SETTING, neu_req_get_node_setting_t) \
|
||||
XX(NEU_RESP_GET_NODE_SETTING, neu_resp_get_node_setting_t) \
|
||||
XX(NEU_REQ_GET_NODE_STATE, neu_req_get_node_state_t) \
|
||||
XX(NEU_RESP_GET_NODE_STATE, neu_resp_get_node_state_t) \
|
||||
XX(NEU_REQ_GET_NODES_STATE, neu_req_get_nodes_state_t) \
|
||||
XX(NEU_RESP_GET_NODES_STATE, neu_resp_get_nodes_state_t) \
|
||||
XX(NEU_REQ_NODE_CTL, neu_req_node_ctl_t) \
|
||||
XX(NEU_REQ_NODE_RENAME, neu_req_node_rename_t) \
|
||||
XX(NEU_RESP_NODE_RENAME, neu_resp_node_rename_t) \
|
||||
XX(NEU_REQ_ADD_GROUP, neu_req_add_group_t) \
|
||||
XX(NEU_REQ_DEL_GROUP, neu_req_del_group_t) \
|
||||
XX(NEU_REQ_UPDATE_GROUP, neu_req_update_group_t) \
|
||||
XX(NEU_REQ_UPDATE_DRIVER_GROUP, neu_req_update_group_t) \
|
||||
XX(NEU_RESP_UPDATE_DRIVER_GROUP, neu_resp_update_group_t) \
|
||||
XX(NEU_REQ_GET_GROUP, neu_req_get_group_t) \
|
||||
XX(NEU_RESP_GET_GROUP, neu_resp_get_group_t) \
|
||||
XX(NEU_REQ_GET_DRIVER_GROUP, neu_req_get_group_t) \
|
||||
XX(NEU_RESP_GET_DRIVER_GROUP, neu_resp_get_driver_group_t) \
|
||||
XX(NEU_REQ_ADD_TAG, neu_req_add_tag_t) \
|
||||
XX(NEU_RESP_ADD_TAG, neu_resp_add_tag_t) \
|
||||
XX(NEU_REQ_ADD_GTAG, neu_req_add_gtag_t) \
|
||||
XX(NEU_RESP_ADD_GTAG, neu_resp_add_tag_t) \
|
||||
XX(NEU_REQ_DEL_TAG, neu_req_del_tag_t) \
|
||||
XX(NEU_REQ_UPDATE_TAG, neu_req_update_tag_t) \
|
||||
XX(NEU_RESP_UPDATE_TAG, neu_resp_update_tag_t) \
|
||||
XX(NEU_REQ_GET_TAG, neu_req_get_tag_t) \
|
||||
XX(NEU_RESP_GET_TAG, neu_resp_get_tag_t) \
|
||||
XX(NEU_REQ_ADD_PLUGIN, neu_req_add_plugin_t) \
|
||||
XX(NEU_REQ_DEL_PLUGIN, neu_req_del_plugin_t) \
|
||||
XX(NEU_REQ_UPDATE_PLUGIN, neu_req_update_plugin_t) \
|
||||
XX(NEU_REQ_GET_PLUGIN, neu_req_get_plugin_t) \
|
||||
XX(NEU_RESP_GET_PLUGIN, neu_resp_get_plugin_t) \
|
||||
XX(NEU_REQRESP_TRANS_DATA, neu_reqresp_trans_data_t) \
|
||||
XX(NEU_REQRESP_NODES_STATE, neu_reqresp_nodes_state_t) \
|
||||
XX(NEU_REQRESP_NODE_DELETED, neu_reqresp_node_deleted_t) \
|
||||
XX(NEU_REQ_ADD_DRIVERS, neu_req_driver_array_t) \
|
||||
XX(NEU_REQ_UPDATE_LOG_LEVEL, neu_req_update_log_level_t) \
|
||||
XX(NEU_REQ_PRGFILE_UPLOAD, neu_req_prgfile_upload_t) \
|
||||
XX(NEU_REQ_PRGFILE_PROCESS, neu_req_prgfile_process_t) \
|
||||
XX(NEU_RESP_PRGFILE_PROCESS, neu_resp_prgfile_process_t) \
|
||||
XX(NEU_REQ_SCAN_TAGS, neu_req_scan_tags_t) \
|
||||
XX(NEU_RESP_SCAN_TAGS, neu_resp_scan_tags_t) \
|
||||
XX(NEU_REQ_CHECK_SCHEMA, neu_req_check_schema_t) \
|
||||
XX(NEU_RESP_CHECK_SCHEMA, neu_resp_check_schema_t) \
|
||||
XX(NEU_REQ_DRIVER_ACTION, neu_req_driver_action_t) \
|
||||
XX(NEU_RESP_DRIVER_ACTION, neu_resp_driver_action_t)
|
||||
#define NEU_REQRESP_TYPE_MAP(XX) \
|
||||
XX(NEU_RESP_ERROR, neu_resp_error_t) \
|
||||
XX(NEU_REQ_READ_GROUP, neu_req_read_group_t) \
|
||||
XX(NEU_RESP_READ_GROUP, neu_resp_read_group_t) \
|
||||
XX(NEU_REQ_READ_GROUP_PAGINATE, neu_req_read_group_paginate_t) \
|
||||
XX(NEU_RESP_READ_GROUP_PAGINATE, neu_resp_read_group_paginate_t) \
|
||||
XX(NEU_REQ_TEST_READ_TAG, neu_req_test_read_tag_t) \
|
||||
XX(NEU_RESP_TEST_READ_TAG, neu_resp_test_read_tag_t) \
|
||||
XX(NEU_REQ_WRITE_TAG, neu_req_write_tag_t) \
|
||||
XX(NEU_REQ_WRITE_TAGS, neu_req_write_tags_t) \
|
||||
XX(NEU_REQ_WRITE_GTAGS, neu_req_write_gtags_t) \
|
||||
XX(NEU_REQ_SUBSCRIBE_GROUP, neu_req_subscribe_t) \
|
||||
XX(NEU_REQ_UNSUBSCRIBE_GROUP, neu_req_unsubscribe_t) \
|
||||
XX(NEU_REQ_UPDATE_SUBSCRIBE_GROUP, neu_req_subscribe_t) \
|
||||
XX(NEU_REQ_SUBSCRIBE_GROUPS, neu_req_subscribe_groups_t) \
|
||||
XX(NEU_REQ_GET_SUBSCRIBE_GROUP, neu_req_get_subscribe_group_t) \
|
||||
XX(NEU_RESP_GET_SUBSCRIBE_GROUP, neu_resp_get_subscribe_group_t) \
|
||||
XX(NEU_REQ_GET_DRIVER_SUBSCRIBE_GROUP, \
|
||||
neu_req_get_driver_subscribe_group_t) \
|
||||
XX(NEU_RESP_GET_DRIVER_SUBSCRIBE_GROUP, neu_resp_get_subscribe_group_t) \
|
||||
XX(NEU_REQ_GET_SUB_DRIVER_TAGS, neu_req_get_sub_driver_tags_t) \
|
||||
XX(NEU_RESP_GET_SUB_DRIVER_TAGS, neu_resp_get_sub_driver_tags_t) \
|
||||
XX(NEU_REQ_NODE_INIT, neu_req_node_init_t) \
|
||||
XX(NEU_REQ_NODE_UNINIT, neu_req_node_uninit_t) \
|
||||
XX(NEU_RESP_NODE_UNINIT, neu_resp_node_uninit_t) \
|
||||
XX(NEU_REQ_ADD_NODE, neu_req_add_node_t) \
|
||||
XX(NEU_REQ_UPDATE_NODE, neu_req_update_node_t) \
|
||||
XX(NEU_REQ_DEL_NODE, neu_req_del_node_t) \
|
||||
XX(NEU_REQ_GET_NODE, neu_req_get_node_t) \
|
||||
XX(NEU_RESP_GET_NODE, neu_resp_get_node_t) \
|
||||
XX(NEU_REQ_NODE_SETTING, neu_req_node_setting_t) \
|
||||
XX(NEU_REQ_GET_NODE_SETTING, neu_req_get_node_setting_t) \
|
||||
XX(NEU_RESP_GET_NODE_SETTING, neu_resp_get_node_setting_t) \
|
||||
XX(NEU_REQ_GET_NODE_STATE, neu_req_get_node_state_t) \
|
||||
XX(NEU_RESP_GET_NODE_STATE, neu_resp_get_node_state_t) \
|
||||
XX(NEU_REQ_GET_NODES_STATE, neu_req_get_nodes_state_t) \
|
||||
XX(NEU_RESP_GET_NODES_STATE, neu_resp_get_nodes_state_t) \
|
||||
XX(NEU_REQ_NODE_CTL, neu_req_node_ctl_t) \
|
||||
XX(NEU_REQ_NODE_RENAME, neu_req_node_rename_t) \
|
||||
XX(NEU_RESP_NODE_RENAME, neu_resp_node_rename_t) \
|
||||
XX(NEU_REQ_ADD_GROUP, neu_req_add_group_t) \
|
||||
XX(NEU_REQ_DEL_GROUP, neu_req_del_group_t) \
|
||||
XX(NEU_REQ_UPDATE_GROUP, neu_req_update_group_t) \
|
||||
XX(NEU_REQ_UPDATE_DRIVER_GROUP, neu_req_update_group_t) \
|
||||
XX(NEU_RESP_UPDATE_DRIVER_GROUP, neu_resp_update_group_t) \
|
||||
XX(NEU_REQ_GET_GROUP, neu_req_get_group_t) \
|
||||
XX(NEU_RESP_GET_GROUP, neu_resp_get_group_t) \
|
||||
XX(NEU_REQ_GET_DRIVER_GROUP, neu_req_get_group_t) \
|
||||
XX(NEU_RESP_GET_DRIVER_GROUP, neu_resp_get_driver_group_t) \
|
||||
XX(NEU_REQ_ADD_TAG, neu_req_add_tag_t) \
|
||||
XX(NEU_RESP_ADD_TAG, neu_resp_add_tag_t) \
|
||||
XX(NEU_REQ_ADD_GTAG, neu_req_add_gtag_t) \
|
||||
XX(NEU_RESP_ADD_GTAG, neu_resp_add_tag_t) \
|
||||
XX(NEU_REQ_DEL_TAG, neu_req_del_tag_t) \
|
||||
XX(NEU_REQ_UPDATE_TAG, neu_req_update_tag_t) \
|
||||
XX(NEU_RESP_UPDATE_TAG, neu_resp_update_tag_t) \
|
||||
XX(NEU_REQ_GET_TAG, neu_req_get_tag_t) \
|
||||
XX(NEU_RESP_GET_TAG, neu_resp_get_tag_t) \
|
||||
XX(NEU_REQ_ADD_PLUGIN, neu_req_add_plugin_t) \
|
||||
XX(NEU_REQ_DEL_PLUGIN, neu_req_del_plugin_t) \
|
||||
XX(NEU_REQ_UPDATE_PLUGIN, neu_req_update_plugin_t) \
|
||||
XX(NEU_REQ_GET_PLUGIN, neu_req_get_plugin_t) \
|
||||
XX(NEU_RESP_GET_PLUGIN, neu_resp_get_plugin_t) \
|
||||
XX(NEU_REQRESP_TRANS_DATA, neu_reqresp_trans_data_t) \
|
||||
XX(NEU_REQRESP_NODES_STATE, neu_reqresp_nodes_state_t) \
|
||||
XX(NEU_REQRESP_NODE_DELETED, neu_reqresp_node_deleted_t) \
|
||||
XX(NEU_REQ_ADD_DRIVERS, neu_req_driver_array_t) \
|
||||
XX(NEU_REQ_UPDATE_LOG_LEVEL, neu_req_update_log_level_t) \
|
||||
XX(NEU_REQ_PRGFILE_UPLOAD, neu_req_prgfile_upload_t) \
|
||||
XX(NEU_REQ_PRGFILE_PROCESS, neu_req_prgfile_process_t) \
|
||||
XX(NEU_RESP_PRGFILE_PROCESS, neu_resp_prgfile_process_t) \
|
||||
XX(NEU_REQ_SCAN_TAGS, neu_req_scan_tags_t) \
|
||||
XX(NEU_RESP_SCAN_TAGS, neu_resp_scan_tags_t) \
|
||||
XX(NEU_REQ_CHECK_SCHEMA, neu_req_check_schema_t) \
|
||||
XX(NEU_RESP_CHECK_SCHEMA, neu_resp_check_schema_t) \
|
||||
XX(NEU_REQ_DRIVER_ACTION, neu_req_driver_action_t) \
|
||||
XX(NEU_RESP_DRIVER_ACTION, neu_resp_driver_action_t) \
|
||||
XX(NEU_REQ_ADD_NODE_EVENT, neu_req_add_node_t) \
|
||||
XX(NEU_REQ_DEL_NODE_EVENT, neu_req_del_node_t) \
|
||||
XX(NEU_REQ_NODE_CTL_EVENT, neu_req_node_ctl_t) \
|
||||
XX(NEU_REQ_NODE_SETTING_EVENT, neu_req_node_setting_t) \
|
||||
XX(NEU_REQ_ADD_GROUP_EVENT, neu_req_add_group_t) \
|
||||
XX(NEU_REQ_DEL_GROUP_EVENT, neu_req_del_group_t) \
|
||||
XX(NEU_REQ_UPDATE_GROUP_EVENT, neu_req_update_group_t) \
|
||||
XX(NEU_REQ_ADD_TAG_EVENT, neu_req_add_tag_t) \
|
||||
XX(NEU_REQ_DEL_TAG_EVENT, neu_req_del_tag_t) \
|
||||
XX(NEU_REQ_UPDATE_TAG_EVENT, neu_req_update_tag_t) \
|
||||
XX(NEU_REQ_ADD_GTAG_EVENT, neu_req_add_gtag_t) \
|
||||
XX(NEU_REQ_ADD_PLUGIN_EVENT, neu_req_add_plugin_t) \
|
||||
XX(NEU_REQ_DEL_PLUGIN_EVENT, neu_req_del_plugin_t) \
|
||||
XX(NEU_REQ_SUBSCRIBE_GROUP_EVENT, neu_req_subscribe_t) \
|
||||
XX(NEU_REQ_UNSUBSCRIBE_GROUP_EVENT, neu_req_unsubscribe_t) \
|
||||
XX(NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT, neu_req_subscribe_t) \
|
||||
XX(NEU_REQ_SUBSCRIBE_GROUPS_EVENT, neu_req_subscribe_groups_t)
|
||||
|
||||
static inline size_t neu_reqresp_size(neu_reqresp_type_e t)
|
||||
{
|
||||
|
||||
@@ -69,6 +69,8 @@ struct neu_conn {
|
||||
uint8_t *buf;
|
||||
uint16_t buf_size;
|
||||
uint16_t offset;
|
||||
|
||||
uint16_t udp_act_port;
|
||||
};
|
||||
|
||||
static void conn_tcp_server_add_client(neu_conn_t *conn, int fd,
|
||||
@@ -503,7 +505,8 @@ ssize_t neu_conn_recv(neu_conn_t *conn, uint8_t *buf, ssize_t len)
|
||||
conn->param.log,
|
||||
"tcp conn fd: %d, recv buf len %zd, ret: %zd, errno: %s(%d)",
|
||||
conn->fd, len, ret, strerror(errno), errno);
|
||||
if (ret == 0 || (ret == -1 && errno != EAGAIN)) {
|
||||
if (ret == 0 ||
|
||||
(conn->connection_ok && ret == -1 && errno != EAGAIN)) {
|
||||
conn_disconnect(conn);
|
||||
}
|
||||
}
|
||||
@@ -868,6 +871,7 @@ static void conn_connect(neu_conn_t *conn)
|
||||
} else {
|
||||
zlog_error(conn->param.log, "invalid ip: %s",
|
||||
conn->param.params.tcp_server.ip);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -938,6 +942,7 @@ static void conn_connect(neu_conn_t *conn)
|
||||
} else {
|
||||
zlog_error(conn->param.log, "invalid ip: %s",
|
||||
conn->param.params.tcp_server.ip);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -950,6 +955,13 @@ static void conn_connect(neu_conn_t *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_in local_addr = { 0 };
|
||||
socklen_t local_addr_len = sizeof(local_addr);
|
||||
if (getsockname(fd, (struct sockaddr *) &local_addr, &local_addr_len) ==
|
||||
0) {
|
||||
conn->udp_act_port = ntohs(local_addr.sin_port);
|
||||
}
|
||||
|
||||
if (is_ipv4(conn->param.params.udp.dst_ip)) {
|
||||
struct sockaddr_in remote = {
|
||||
.sin_family = AF_INET,
|
||||
@@ -1053,6 +1065,13 @@ static void conn_connect(neu_conn_t *conn)
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_in local_addr = { 0 };
|
||||
socklen_t local_addr_len = sizeof(local_addr);
|
||||
if (getsockname(fd, (struct sockaddr *) &local_addr, &local_addr_len) ==
|
||||
0) {
|
||||
conn->udp_act_port = ntohs(local_addr.sin_port);
|
||||
}
|
||||
|
||||
conn->is_connected = true;
|
||||
conn->fd = fd;
|
||||
|
||||
@@ -1464,4 +1483,9 @@ int is_ipv6(const char *ip)
|
||||
bool neu_conn_is_connected(neu_conn_t *conn)
|
||||
{
|
||||
return conn->is_connected;
|
||||
}
|
||||
|
||||
uint16_t neu_conn_udp_act_port(neu_conn_t *conn)
|
||||
{
|
||||
return conn->udp_act_port;
|
||||
}
|
||||
@@ -137,7 +137,7 @@ neu_conn_eth_t *neu_conn_eth_init(const char *interface, void *ctx)
|
||||
conn_eth->ic = &in_conns[i];
|
||||
|
||||
in_conns[i].interface = strdup(interface);
|
||||
in_conns[i].events = neu_event_new();
|
||||
in_conns[i].events = neu_event_new("eth_conn");
|
||||
in_conns[i].count += 1;
|
||||
|
||||
get_mac(conn_eth, interface);
|
||||
|
||||
@@ -907,7 +907,7 @@ static inline int client_start_timer(neu_mqtt_client_t *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
events = neu_event_new();
|
||||
events = neu_event_new("mqtt_client");
|
||||
if (NULL == events) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
+99
-10
@@ -63,6 +63,8 @@ inline static void forward_msg_copy(neu_manager_t * manager,
|
||||
neu_reqresp_head_t *header,
|
||||
const char * node);
|
||||
|
||||
inline static void notify_monitor(neu_manager_t * manager,
|
||||
neu_reqresp_type_e event, void *data);
|
||||
static void start_static_adapter(neu_manager_t *manager, const char *name);
|
||||
static int update_timestamp(void *usr_data);
|
||||
static void start_single_adapter(neu_manager_t *manager, const char *name,
|
||||
@@ -96,7 +98,7 @@ neu_manager_t *neu_manager_create()
|
||||
.type = NEU_EVENT_TIMER_NOBLOCK,
|
||||
};
|
||||
|
||||
manager->events = neu_event_new();
|
||||
manager->events = neu_event_new("manager");
|
||||
manager->plugin_manager = neu_plugin_manager_create();
|
||||
manager->node_manager = neu_node_manager_create();
|
||||
manager->subscribe_manager = neu_subscribe_manager_create();
|
||||
@@ -230,10 +232,12 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
header = neu_msg_get_header(msg);
|
||||
header = neu_msg_get_header(msg);
|
||||
header->monitor = neu_node_manager_find(manager->node_manager, "monitor");
|
||||
|
||||
nlog_info("manager recv msg from: %s to %s, type: %s", header->sender,
|
||||
header->receiver, neu_reqresp_type_string(header->type));
|
||||
nlog_info("manager recv msg from: %s to %s, type: %s, monitor: %d",
|
||||
header->sender, header->receiver,
|
||||
neu_reqresp_type_string(header->type), header->monitor);
|
||||
switch (header->type) {
|
||||
case NEU_REQ_NODE_INIT: {
|
||||
neu_req_node_init_t *init = (neu_req_node_init_t *) &header[1];
|
||||
@@ -418,6 +422,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
|
||||
if (error == NEU_ERR_SUCCESS) {
|
||||
manager_strorage_plugin(manager);
|
||||
// notify_monitor(manager, NEU_REQ_ADD_PLUGIN_EVENT, cmd);
|
||||
}
|
||||
|
||||
free(so_tmp_path);
|
||||
@@ -435,7 +440,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
neu_resp_error_t e = { 0 };
|
||||
|
||||
UT_array *nodes = neu_manager_get_nodes(
|
||||
manager, NEU_NA_TYPE_DRIVER | NEU_NA_TYPE_APP, cmd->plugin, "");
|
||||
manager, NEU_NA_TYPE_DRIVER | NEU_NA_TYPE_APP, cmd->plugin, "",
|
||||
false, false, 0, false, 0, "");
|
||||
|
||||
if (nodes != NULL) {
|
||||
if (utarray_len(nodes) > 0) {
|
||||
@@ -454,6 +460,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
|
||||
if (error == NEU_ERR_SUCCESS) {
|
||||
manager_strorage_plugin(manager);
|
||||
// notify_monitor(manager, NEU_REQ_DEL_PLUGIN_EVENT, cmd);
|
||||
}
|
||||
|
||||
header->type = NEU_RESP_ERROR;
|
||||
@@ -616,7 +623,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
}
|
||||
|
||||
UT_array *nodes = neu_manager_get_nodes(
|
||||
manager, NEU_NA_TYPE_DRIVER | NEU_NA_TYPE_APP, module_name, "");
|
||||
manager, NEU_NA_TYPE_DRIVER | NEU_NA_TYPE_APP, module_name, "",
|
||||
false, false, 0, false, 0, "");
|
||||
|
||||
if (nodes != NULL) {
|
||||
if (utarray_len(nodes) > 0) {
|
||||
@@ -734,6 +742,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
if (cmd->setting) {
|
||||
adapter_storage_setting(cmd->node, cmd->setting);
|
||||
}
|
||||
notify_monitor(manager, NEU_REQ_ADD_NODE_EVENT, cmd);
|
||||
}
|
||||
|
||||
neu_req_add_node_fini(cmd);
|
||||
@@ -816,6 +825,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
utarray_free(subscriptions);
|
||||
}
|
||||
|
||||
notify_monitor(manager, NEU_REQ_DEL_NODE_EVENT, cmd);
|
||||
neu_reqresp_node_deleted_t resp = { 0 };
|
||||
strcpy(resp.node, header->receiver);
|
||||
// notify MQTT about node removal
|
||||
@@ -866,9 +876,11 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_GET_NODE: {
|
||||
neu_req_get_node_t *cmd = (neu_req_get_node_t *) &header[1];
|
||||
UT_array * nodes =
|
||||
neu_manager_get_nodes(manager, cmd->type, cmd->plugin, cmd->node);
|
||||
neu_req_get_node_t *cmd = (neu_req_get_node_t *) &header[1];
|
||||
UT_array * nodes = neu_manager_get_nodes(
|
||||
manager, cmd->type, cmd->plugin, cmd->node, cmd->query.s_delay,
|
||||
cmd->query.q_state, cmd->query.state, cmd->query.q_link,
|
||||
cmd->query.link, cmd->query.q_group_name);
|
||||
neu_resp_get_node_t resp = { .nodes = nodes };
|
||||
|
||||
header->type = NEU_RESP_GET_NODE;
|
||||
@@ -955,6 +967,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
manager_storage_update_subscribe(manager, cmd->app, cmd->driver,
|
||||
cmd->group, cmd->params,
|
||||
cmd->static_tags);
|
||||
notify_monitor(manager, NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT, cmd);
|
||||
} else {
|
||||
free(cmd->params);
|
||||
}
|
||||
@@ -977,6 +990,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
forward_msg_copy(manager, header, cmd->driver);
|
||||
manager_storage_unsubscribe(manager, cmd->app, cmd->driver,
|
||||
cmd->group);
|
||||
notify_monitor(manager, NEU_REQ_UNSUBSCRIBE_GROUP_EVENT, cmd);
|
||||
}
|
||||
|
||||
header->type = NEU_RESP_ERROR;
|
||||
@@ -996,6 +1010,18 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
reply(manager, header, &resp);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_GET_DRIVER_SUBSCRIBE_GROUP: {
|
||||
neu_req_get_driver_subscribe_group_t *cmd =
|
||||
(neu_req_get_driver_subscribe_group_t *) &header[1];
|
||||
UT_array *groups =
|
||||
neu_manager_get_driver_groups(manager, cmd->app, cmd->name);
|
||||
neu_resp_get_subscribe_group_t resp = { .groups = groups };
|
||||
|
||||
strcpy(header->receiver, header->sender);
|
||||
header->type = NEU_RESP_GET_DRIVER_SUBSCRIBE_GROUP;
|
||||
reply(manager, header, &resp);
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_GET_SUB_DRIVER_TAGS: {
|
||||
neu_req_get_sub_driver_tags_t *cmd =
|
||||
(neu_req_get_sub_driver_tags_t *) &header[1];
|
||||
@@ -1324,7 +1350,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_NODE_SETTING: {
|
||||
case NEU_REQ_NODE_SETTING:
|
||||
case NEU_REQ_NODE_SETTING_EVENT: {
|
||||
neu_req_node_setting_t *cmd = (neu_req_node_setting_t *) &header[1];
|
||||
|
||||
if (neu_node_manager_find(manager->node_manager, header->receiver) ==
|
||||
@@ -1435,6 +1462,27 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
|
||||
break;
|
||||
}
|
||||
case NEU_REQ_ADD_NODE_EVENT:
|
||||
case NEU_REQ_DEL_NODE_EVENT:
|
||||
case NEU_REQ_NODE_CTL_EVENT:
|
||||
case NEU_REQ_ADD_GROUP_EVENT:
|
||||
case NEU_REQ_DEL_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_GROUP_EVENT:
|
||||
case NEU_REQ_ADD_TAG_EVENT:
|
||||
case NEU_REQ_DEL_TAG_EVENT:
|
||||
case NEU_REQ_UPDATE_TAG_EVENT:
|
||||
case NEU_REQ_ADD_GTAG_EVENT:
|
||||
case NEU_REQ_ADD_PLUGIN_EVENT:
|
||||
case NEU_REQ_DEL_PLUGIN_EVENT:
|
||||
case NEU_REQ_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UPDATE_SUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_UNSUBSCRIBE_GROUP_EVENT:
|
||||
case NEU_REQ_SUBSCRIBE_GROUPS_EVENT: {
|
||||
if (neu_node_manager_find(manager->node_manager, header->receiver)) {
|
||||
forward_msg(manager, header, header->receiver);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
nlog_warn("unknown msg type: %d", header->type);
|
||||
assert(false);
|
||||
@@ -1672,3 +1720,44 @@ static bool mv_tmp_schema_file(neu_plugin_kind_e kind, const char *tmp_path,
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct notify_monitor_ctx {
|
||||
neu_manager_t * manager;
|
||||
neu_reqresp_type_e event;
|
||||
void * data;
|
||||
};
|
||||
|
||||
inline static void notify_monitor(neu_manager_t * manager,
|
||||
neu_reqresp_type_e event, void *data)
|
||||
{
|
||||
struct notify_monitor_ctx ctx = {
|
||||
.manager = manager,
|
||||
.event = event,
|
||||
.data = data,
|
||||
};
|
||||
|
||||
// monitor not ready, ignore
|
||||
neu_node_manager_t *mgr = manager->node_manager;
|
||||
struct sockaddr_un addr = neu_node_manager_get_addr(mgr, "monitor");
|
||||
if (0 == addr.sun_path) {
|
||||
return;
|
||||
}
|
||||
|
||||
// message header
|
||||
neu_msg_t *msg = neu_msg_new(ctx.event, NULL, ctx.data);
|
||||
if (NULL == msg) {
|
||||
return;
|
||||
}
|
||||
neu_reqresp_head_t *header = neu_msg_get_header(msg);
|
||||
strcpy(header->sender, "manager");
|
||||
strcpy(header->receiver, "monitor");
|
||||
|
||||
int ret = neu_send_msg_to(manager->server_fd, &addr, msg);
|
||||
if (0 != ret) {
|
||||
nlog_warn("notify %s of %s, error: %s(%d)", header->receiver,
|
||||
neu_reqresp_type_string(header->type), strerror(errno),
|
||||
errno);
|
||||
neu_msg_free(msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -114,9 +114,13 @@ int neu_manager_del_node(neu_manager_t *manager, const char *node_name)
|
||||
}
|
||||
|
||||
UT_array *neu_manager_get_nodes(neu_manager_t *manager, int type,
|
||||
const char *plugin, const char *node)
|
||||
const char *plugin, const char *node,
|
||||
bool sort_delay, bool q_state, int state,
|
||||
bool q_link, int link, const char *q_group_name)
|
||||
{
|
||||
return neu_node_manager_filter(manager->node_manager, type, plugin, node);
|
||||
return neu_node_manager_filter(manager->node_manager, type, plugin, node,
|
||||
sort_delay, q_state, state, q_link, link,
|
||||
q_group_name);
|
||||
}
|
||||
|
||||
int neu_manager_update_node_name(neu_manager_t *manager, const char *node,
|
||||
@@ -182,7 +186,7 @@ UT_array *neu_manager_get_driver_group(neu_manager_t *manager)
|
||||
neu_adapter_t *adapter =
|
||||
neu_node_manager_find(manager->node_manager, driver->node);
|
||||
UT_array *groups =
|
||||
neu_adapter_driver_get_group((neu_adapter_driver_t *) adapter);
|
||||
neu_adapter_driver_get_group((neu_adapter_driver_t *) adapter, "");
|
||||
|
||||
utarray_foreach(groups, neu_resp_group_info_t *, g)
|
||||
{
|
||||
@@ -233,6 +237,10 @@ int neu_manager_subscribe(neu_manager_t *manager, const char *app,
|
||||
const char *params, const char *static_tags,
|
||||
uint16_t *app_port)
|
||||
{
|
||||
if (neu_node_manager_is_monitor(manager->node_manager, app)) {
|
||||
return NEU_ERR_NODE_NOT_ALLOW_SUBSCRIBE;
|
||||
}
|
||||
|
||||
neu_adapter_t *adapter = neu_node_manager_find(manager->node_manager, app);
|
||||
|
||||
if (adapter == NULL) {
|
||||
@@ -372,6 +380,55 @@ UT_array *neu_manager_get_sub_group_deep_copy(neu_manager_t *manager,
|
||||
return subs;
|
||||
}
|
||||
|
||||
UT_array *neu_manager_get_driver_groups(neu_manager_t *manager, const char *app,
|
||||
const char *name)
|
||||
{
|
||||
UT_icd icd = { sizeof(neu_resp_driver_subscribe_info_t), NULL, NULL, NULL };
|
||||
UT_array *result = NULL;
|
||||
|
||||
UT_array *sub_groups =
|
||||
neu_subscribe_manager_get(manager->subscribe_manager, app, NULL, NULL);
|
||||
UT_array *driver_groups = neu_manager_get_driver_group(manager);
|
||||
|
||||
utarray_new(result, &icd);
|
||||
utarray_foreach(driver_groups, neu_resp_driver_group_info_t *, grp)
|
||||
{
|
||||
neu_resp_driver_subscribe_info_t info = { 0 };
|
||||
|
||||
if (name != NULL && strlen(name) > 0) {
|
||||
if (strstr(grp->driver, name) != NULL ||
|
||||
strstr(grp->group, name) != NULL) {
|
||||
strcpy(info.app, app);
|
||||
strcpy(info.driver, grp->driver);
|
||||
strcpy(info.group, grp->group);
|
||||
info.subscribed = false;
|
||||
}
|
||||
} else {
|
||||
strcpy(info.app, app);
|
||||
strcpy(info.driver, grp->driver);
|
||||
strcpy(info.group, grp->group);
|
||||
info.subscribed = false;
|
||||
}
|
||||
|
||||
if (strlen(info.driver) > 0 && strlen(info.group) > 0) {
|
||||
utarray_foreach(sub_groups, neu_resp_subscribe_info_t *, sub)
|
||||
{
|
||||
if (strcmp(sub->driver, info.driver) == 0 &&
|
||||
strcmp(sub->group, info.group) == 0) {
|
||||
info.subscribed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
utarray_push_back(result, &info);
|
||||
}
|
||||
}
|
||||
|
||||
utarray_free(sub_groups);
|
||||
utarray_free(driver_groups);
|
||||
return result;
|
||||
}
|
||||
|
||||
int neu_manager_get_node_info(neu_manager_t *manager, const char *name,
|
||||
neu_persist_node_info_t *info)
|
||||
{
|
||||
|
||||
@@ -56,7 +56,10 @@ int neu_manager_add_node(neu_manager_t *manager, const char *node_name,
|
||||
neu_node_running_state_e state, bool load);
|
||||
int neu_manager_del_node(neu_manager_t *manager, const char *node_name);
|
||||
UT_array *neu_manager_get_nodes(neu_manager_t *manager, int type,
|
||||
const char *plugin, const char *node);
|
||||
const char *plugin, const char *node,
|
||||
bool sort_delay, bool q_state, int state,
|
||||
bool q_link, int link,
|
||||
const char *q_group_name);
|
||||
int neu_manager_update_node_name(neu_manager_t *manager, const char *node,
|
||||
const char *new_name);
|
||||
int neu_manager_update_group_name(neu_manager_t *manager, const char *driver,
|
||||
@@ -82,6 +85,8 @@ UT_array *neu_manager_get_sub_group_deep_copy(neu_manager_t *manager,
|
||||
const char * app,
|
||||
const char * driver,
|
||||
const char * group);
|
||||
UT_array *neu_manager_get_driver_groups(neu_manager_t *manager, const char *app,
|
||||
const char *name);
|
||||
|
||||
int neu_manager_get_node_info(neu_manager_t *manager, const char *name,
|
||||
neu_persist_node_info_t *info);
|
||||
|
||||
+102
-1
@@ -32,6 +32,7 @@ typedef struct node_entity {
|
||||
bool is_static;
|
||||
bool display;
|
||||
bool single;
|
||||
bool is_monitor;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
UT_hash_handle hh;
|
||||
@@ -39,11 +40,17 @@ typedef struct node_entity {
|
||||
|
||||
struct neu_node_manager {
|
||||
node_entity_t *nodes;
|
||||
UT_array * monitors;
|
||||
};
|
||||
|
||||
neu_node_manager_t *neu_node_manager_create()
|
||||
{
|
||||
neu_node_manager_t *node_manager = calloc(1, sizeof(neu_node_manager_t));
|
||||
|
||||
if (node_manager) {
|
||||
utarray_new(node_manager->monitors, &ut_ptr_icd);
|
||||
}
|
||||
|
||||
return node_manager;
|
||||
}
|
||||
|
||||
@@ -58,6 +65,7 @@ void neu_node_manager_destroy(neu_node_manager_t *mgr)
|
||||
free(el);
|
||||
}
|
||||
|
||||
utarray_free(mgr->monitors);
|
||||
free(mgr);
|
||||
}
|
||||
|
||||
@@ -68,9 +76,15 @@ int neu_node_manager_add(neu_node_manager_t *mgr, neu_adapter_t *adapter)
|
||||
node->adapter = adapter;
|
||||
node->name = strdup(adapter->name);
|
||||
node->display = true;
|
||||
node->is_monitor =
|
||||
(0 == strcmp(node->adapter->module->module_name, "Monitor"));
|
||||
|
||||
HASH_ADD_STR(mgr->nodes, name, node);
|
||||
|
||||
if (node->is_monitor) {
|
||||
utarray_push_back(mgr->monitors, &node);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -147,6 +161,10 @@ void neu_node_manager_del(neu_node_manager_t *mgr, const char *name)
|
||||
HASH_FIND_STR(mgr->nodes, name, node);
|
||||
if (node != NULL) {
|
||||
HASH_DEL(mgr->nodes, node);
|
||||
if (node->is_monitor) {
|
||||
utarray_erase(mgr->monitors, utarray_eltidx(mgr->monitors, node),
|
||||
1);
|
||||
}
|
||||
free(node->name);
|
||||
free(node);
|
||||
}
|
||||
@@ -194,8 +212,24 @@ UT_array *neu_node_manager_get(neu_node_manager_t *mgr, int type)
|
||||
return array;
|
||||
}
|
||||
|
||||
static int neu_resp_node_info_sort(const void *a, const void *b)
|
||||
{
|
||||
const neu_resp_node_info_t *info_a = (const neu_resp_node_info_t *) a;
|
||||
const neu_resp_node_info_t *info_b = (const neu_resp_node_info_t *) b;
|
||||
|
||||
if (info_a->delay < info_b->delay) {
|
||||
return -1;
|
||||
} else if (info_a->delay > info_b->delay) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
UT_array *neu_node_manager_filter(neu_node_manager_t *mgr, int type,
|
||||
const char *plugin, const char *node)
|
||||
const char *plugin, const char *node,
|
||||
bool sort_delay, bool q_state, int state,
|
||||
bool q_link, int link,
|
||||
const char *q_group_name)
|
||||
{
|
||||
UT_array * array = NULL;
|
||||
UT_icd icd = { sizeof(neu_resp_node_info_t), NULL, NULL, NULL };
|
||||
@@ -215,14 +249,57 @@ UT_array *neu_node_manager_filter(neu_node_manager_t *mgr, int type,
|
||||
strstr(el->adapter->name, node) == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (q_state) {
|
||||
if (el->adapter->state !=
|
||||
(neu_node_running_state_e) state) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (q_link) {
|
||||
neu_node_state_t node_state =
|
||||
neu_adapter_get_state(el->adapter);
|
||||
if (node_state.link != (neu_node_link_state_e) link) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(q_group_name) > 0) {
|
||||
if (strstr(el->adapter->name, q_group_name) == NULL) {
|
||||
UT_array *groups =
|
||||
neu_adapter_get_groups(el->adapter, q_group_name);
|
||||
if (NULL == groups || utarray_len(groups) == 0) {
|
||||
if (groups != NULL) {
|
||||
utarray_free(groups);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
utarray_free(groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
neu_resp_node_info_t info = { 0 };
|
||||
strcpy(info.node, el->adapter->name);
|
||||
strcpy(info.plugin, el->adapter->module->module_name);
|
||||
if (sort_delay) {
|
||||
neu_metric_entry_t *e = NULL;
|
||||
if (NULL != el->adapter->metrics) {
|
||||
HASH_FIND_STR(el->adapter->metrics->entries,
|
||||
NEU_METRIC_LAST_RTT_MS, e);
|
||||
}
|
||||
info.delay = NULL != e ? e->value : 0;
|
||||
} else {
|
||||
info.delay = 0;
|
||||
}
|
||||
utarray_push_back(array, &info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sort_delay) {
|
||||
utarray_sort(array, neu_resp_node_info_sort);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -348,6 +425,30 @@ struct sockaddr_un neu_node_manager_get_addr(neu_node_manager_t *mgr,
|
||||
return addr;
|
||||
}
|
||||
|
||||
bool neu_node_manager_is_monitor(neu_node_manager_t *mgr, const char *name)
|
||||
{
|
||||
node_entity_t *node = NULL;
|
||||
HASH_FIND_STR(mgr->nodes, name, node);
|
||||
return node ? node->is_monitor : false;
|
||||
}
|
||||
|
||||
/*int neu_node_manager_for_each_monitor(neu_node_manager_t *mgr,
|
||||
int (*cb)(const char * name,
|
||||
struct sockaddr_un addr,
|
||||
void * data),
|
||||
void *data)
|
||||
{
|
||||
int rv = 0;
|
||||
utarray_foreach(mgr->monitors, node_entity_t **, node)
|
||||
{
|
||||
rv = cb((*node)->name, (*node)->addr, data);
|
||||
if (0 != rv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}*/
|
||||
|
||||
UT_array *neu_node_manager_get_state(neu_node_manager_t *mgr)
|
||||
{
|
||||
UT_icd icd = { sizeof(neu_nodes_state_t), NULL, NULL, NULL };
|
||||
|
||||
@@ -49,7 +49,10 @@ uint16_t neu_node_manager_size(neu_node_manager_t *mgr);
|
||||
// neu_resp_node_info array
|
||||
UT_array *neu_node_manager_get(neu_node_manager_t *mgr, int type);
|
||||
UT_array *neu_node_manager_filter(neu_node_manager_t *mgr, int type,
|
||||
const char *plugin, const char *node);
|
||||
const char *plugin, const char *node,
|
||||
bool sort_delay, bool q_state, int state,
|
||||
bool q_link, int link,
|
||||
const char *q_group_name);
|
||||
UT_array *neu_node_manager_get_all(neu_node_manager_t *mgr);
|
||||
|
||||
// neu_adapter_t array
|
||||
@@ -64,6 +67,8 @@ UT_array *neu_node_manager_get_addrs_all(neu_node_manager_t *mgr);
|
||||
struct sockaddr_un neu_node_manager_get_addr(neu_node_manager_t *mgr,
|
||||
const char * name);
|
||||
|
||||
bool neu_node_manager_is_monitor(neu_node_manager_t *mgr, const char *name);
|
||||
|
||||
// neu_nodes_state_t array
|
||||
UT_array *neu_node_manager_get_state(neu_node_manager_t *mgr);
|
||||
|
||||
|
||||
+21
-16
@@ -72,6 +72,7 @@ struct neu_events {
|
||||
int epoll_fd;
|
||||
pthread_t thread;
|
||||
bool stop;
|
||||
char * name;
|
||||
|
||||
pthread_mutex_t mtx;
|
||||
int n_event;
|
||||
@@ -122,8 +123,8 @@ static void *event_loop(void *arg)
|
||||
}
|
||||
|
||||
if (ret == -1 || events->stop) {
|
||||
zlog_warn(neuron, "event loop exit, errno: %s(%d), stop: %d",
|
||||
strerror(errno), errno, events->stop);
|
||||
zlog_warn(neuron, "event loop(%s) exit, errno: %s(%d), stop: %d",
|
||||
events->name, strerror(errno), errno, events->stop);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -177,17 +178,18 @@ static void *event_loop(void *arg)
|
||||
return NULL;
|
||||
};
|
||||
|
||||
neu_events_t *neu_event_new(void)
|
||||
neu_events_t *neu_event_new(const char *name)
|
||||
{
|
||||
neu_events_t *events = calloc(1, sizeof(struct neu_events));
|
||||
|
||||
events->epoll_fd = epoll_create(1);
|
||||
|
||||
nlog_notice("create epoll: %d(%d)", events->epoll_fd, errno);
|
||||
nlog_notice("create epoll(%s): %d(%d)", name, events->epoll_fd, errno);
|
||||
assert(events->epoll_fd > 0);
|
||||
|
||||
events->stop = false;
|
||||
events->n_event = 0;
|
||||
events->name = strdup(name);
|
||||
pthread_mutex_init(&events->mtx, NULL);
|
||||
|
||||
pthread_create(&events->thread, NULL, event_loop, events);
|
||||
@@ -199,6 +201,7 @@ int neu_event_close(neu_events_t *events)
|
||||
{
|
||||
events->stop = true;
|
||||
close(events->epoll_fd);
|
||||
free(events->name);
|
||||
|
||||
pthread_join(events->thread, NULL);
|
||||
pthread_mutex_destroy(&events->mtx);
|
||||
@@ -220,7 +223,8 @@ neu_event_timer_t *neu_event_add_timer(neu_events_t * events,
|
||||
};
|
||||
int index = get_free_event(events);
|
||||
if (index < 0) {
|
||||
zlog_fatal(neuron, "no free event: %d", events->epoll_fd);
|
||||
zlog_fatal(neuron, "no free event(%s): %d", events->name,
|
||||
events->epoll_fd);
|
||||
}
|
||||
assert(index >= 0);
|
||||
|
||||
@@ -251,18 +255,19 @@ neu_event_timer_t *neu_event_add_timer(neu_events_t * events,
|
||||
|
||||
zlog_notice(neuron,
|
||||
"add timer, second: %" PRId64 ", millisecond: %" PRId64
|
||||
", timer: %d in epoll %d, "
|
||||
", timer: %d in epoll(%s) %d, "
|
||||
"ret: %d, index: %d",
|
||||
timer.second, timer.millisecond, timer_fd, events->epoll_fd,
|
||||
ret, index);
|
||||
timer.second, timer.millisecond, timer_fd, events->name,
|
||||
events->epoll_fd, ret, index);
|
||||
|
||||
return timer_ctx;
|
||||
}
|
||||
|
||||
int neu_event_del_timer(neu_events_t *events, neu_event_timer_t *timer)
|
||||
{
|
||||
zlog_notice(neuron, "del timer: %d from epoll: %d, index: %d", timer->fd,
|
||||
events->epoll_fd, timer->event_data->index);
|
||||
zlog_notice(neuron, "del timer: %d from epoll(%s): %d, index: %d",
|
||||
timer->fd, events->name, events->epoll_fd,
|
||||
timer->event_data->index);
|
||||
|
||||
timer->stop = true;
|
||||
epoll_ctl(events->epoll_fd, EPOLL_CTL_DEL, timer->fd, NULL);
|
||||
@@ -281,8 +286,8 @@ neu_event_io_t *neu_event_add_io(neu_events_t *events, neu_event_io_param_t io)
|
||||
int ret = 0;
|
||||
int index = get_free_event(events);
|
||||
|
||||
nlog_notice("add io, fd: %d, epoll: %d, index: %d", io.fd, events->epoll_fd,
|
||||
index);
|
||||
nlog_notice("add io, fd: %d, epoll(%s): %d, index: %d", io.fd, events->name,
|
||||
events->epoll_fd, index);
|
||||
assert(index >= 0);
|
||||
|
||||
neu_event_io_t *io_ctx = &events->event_datas[index].ctx.io;
|
||||
@@ -303,8 +308,8 @@ neu_event_io_t *neu_event_add_io(neu_events_t *events, neu_event_io_param_t io)
|
||||
|
||||
ret = epoll_ctl(events->epoll_fd, EPOLL_CTL_ADD, io.fd, &event);
|
||||
|
||||
nlog_notice("add io, fd: %d, epoll: %d, ret: %d(%d), index: %d", io.fd,
|
||||
events->epoll_fd, ret, errno, index);
|
||||
nlog_notice("add io, fd: %d, epoll(%s): %d, ret: %d(%d), index: %d", io.fd,
|
||||
events->name, events->epoll_fd, ret, errno, index);
|
||||
assert(ret == 0);
|
||||
|
||||
return io_ctx;
|
||||
@@ -316,8 +321,8 @@ int neu_event_del_io(neu_events_t *events, neu_event_io_t *io)
|
||||
return 0;
|
||||
}
|
||||
|
||||
zlog_notice(neuron, "del io: %d from epoll: %d, index: %d", io->fd,
|
||||
events->epoll_fd, io->event_data->index);
|
||||
zlog_notice(neuron, "del io: %d from epoll(%s): %d, index: %d", io->fd,
|
||||
events->name, events->epoll_fd, io->event_data->index);
|
||||
|
||||
epoll_ctl(events->epoll_fd, EPOLL_CTL_DEL, io->fd, NULL);
|
||||
free_event(events, io->event_data->index);
|
||||
|
||||
@@ -1113,7 +1113,7 @@ static int otel_timer_cb(void *data)
|
||||
void neu_otel_start()
|
||||
{
|
||||
if (otel_event == NULL) {
|
||||
otel_event = neu_event_new();
|
||||
otel_event = neu_event_new("otel_event");
|
||||
}
|
||||
|
||||
if (otel_timer == NULL) {
|
||||
|
||||
@@ -32,6 +32,30 @@
|
||||
|
||||
#include "neu_json_group_config.h"
|
||||
|
||||
int neu_json_encode_add_group_config_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_add_group_config_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->group,
|
||||
},
|
||||
{
|
||||
.name = "interval",
|
||||
.t = NEU_JSON_INT,
|
||||
.v.val_int = req->interval,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_add_group_config_req(
|
||||
char *buf, neu_json_add_group_config_req_t **result)
|
||||
{
|
||||
@@ -90,6 +114,25 @@ void neu_json_decode_add_group_config_req_free(
|
||||
free(req);
|
||||
}
|
||||
|
||||
int neu_json_encode_del_group_config_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_del_group_config_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->group,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_del_group_config_req(
|
||||
char *buf, neu_json_del_group_config_req_t **result)
|
||||
{
|
||||
@@ -362,11 +405,88 @@ int neu_json_encode_get_subscribe_resp(void *object, void *param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_encode_get_driver_subscribe_resp(void *object, void *param)
|
||||
{
|
||||
|
||||
neu_json_get_driver_subscribe_resp_t *resp =
|
||||
(neu_json_get_driver_subscribe_resp_t *) param;
|
||||
|
||||
void *driver_array = neu_json_array();
|
||||
for (int i = 0; i < resp->n_driver; i++) {
|
||||
if (resp->drivers[i].n_group == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
json_t *ob = json_object();
|
||||
void * group_array = neu_json_array();
|
||||
|
||||
json_object_set_new(ob, "name", json_string(resp->drivers[i].driver));
|
||||
|
||||
for (int j = 0; j < resp->drivers[i].n_group; j++) {
|
||||
json_t *group_ob = json_object();
|
||||
|
||||
json_object_set_new(group_ob, "name",
|
||||
json_string(resp->drivers[i].groups[j].group));
|
||||
json_object_set_new(
|
||||
group_ob, "subscribed",
|
||||
json_boolean(resp->drivers[i].groups[j].subscribed));
|
||||
|
||||
json_array_append_new(group_array, group_ob);
|
||||
}
|
||||
|
||||
json_object_set_new(ob, "groups", group_array);
|
||||
|
||||
json_array_append_new(driver_array, ob);
|
||||
}
|
||||
|
||||
neu_json_elem_t resp_elems[] = { {
|
||||
.name = "drivers",
|
||||
.t = NEU_JSON_OBJECT,
|
||||
.v.val_object = driver_array,
|
||||
} };
|
||||
|
||||
return neu_json_encode_field(object, resp_elems,
|
||||
NEU_JSON_ELEM_SIZE(resp_elems));
|
||||
}
|
||||
|
||||
static inline int dump_params(void *root, char **const result)
|
||||
{
|
||||
return neu_json_dump_key(root, "params", result, false);
|
||||
}
|
||||
|
||||
int neu_json_encode_subscribe_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_subscribe_req_t *req = param;
|
||||
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "app",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->app,
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->group,
|
||||
},
|
||||
{
|
||||
.name = "driver",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->driver,
|
||||
},
|
||||
{
|
||||
.name = "params",
|
||||
.t = NEU_JSON_OBJECT,
|
||||
.v.val_object = req->params
|
||||
? json_loads(req->params, 0, NULL)
|
||||
: NULL,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_subscribe_req(char *buf, neu_json_subscribe_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -437,6 +557,30 @@ void neu_json_decode_subscribe_req_free(neu_json_subscribe_req_t *req)
|
||||
free(req);
|
||||
}
|
||||
|
||||
int neu_json_encode_unsubscribe_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_unsubscribe_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "app",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->app,
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->group,
|
||||
},
|
||||
{
|
||||
.name = "driver",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->driver,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_unsubscribe_req(char * buf,
|
||||
neu_json_unsubscribe_req_t **result)
|
||||
{
|
||||
@@ -496,6 +640,41 @@ void neu_json_decode_unsubscribe_req_free(neu_json_unsubscribe_req_t *req)
|
||||
free(req);
|
||||
}
|
||||
|
||||
int neu_json_encode_update_group_config_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_update_group_config_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->group,
|
||||
},
|
||||
{
|
||||
.name = "new_name",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->new_name,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
if (0 != ret) {
|
||||
return ret;
|
||||
}
|
||||
if (req->set_interval) {
|
||||
neu_json_elem_t interval_elem = {
|
||||
.name = "interval",
|
||||
.t = NEU_JSON_INT,
|
||||
.v.val_int = req->interval,
|
||||
};
|
||||
ret = neu_json_encode_field(json_object, &interval_elem, 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_update_group_config_req(
|
||||
char *buf, neu_json_update_group_config_req_t **result)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@ typedef struct {
|
||||
int64_t interval;
|
||||
} neu_json_add_group_config_req_t, neu_json_update_group_req_t;
|
||||
|
||||
int neu_json_encode_add_group_config_req(void *json_object, void *param);
|
||||
int neu_json_decode_add_group_config_req(
|
||||
char *buf, neu_json_add_group_config_req_t **result);
|
||||
void neu_json_decode_add_group_config_req_free(
|
||||
@@ -50,6 +51,7 @@ typedef struct {
|
||||
int64_t interval;
|
||||
} neu_json_update_group_config_req_t;
|
||||
|
||||
int neu_json_encode_update_group_config_req(void *json_object, void *param);
|
||||
int neu_json_decode_update_group_config_req(
|
||||
char *buf, neu_json_update_group_config_req_t **result);
|
||||
void neu_json_decode_update_group_config_req_free(
|
||||
@@ -60,6 +62,7 @@ typedef struct {
|
||||
char *node;
|
||||
} neu_json_del_group_config_req_t;
|
||||
|
||||
int neu_json_encode_del_group_config_req(void *json_object, void *param);
|
||||
int neu_json_decode_del_group_config_req(
|
||||
char *buf, neu_json_del_group_config_req_t **result);
|
||||
void neu_json_decode_del_group_config_req_free(
|
||||
@@ -110,6 +113,24 @@ typedef struct {
|
||||
|
||||
int neu_json_encode_get_subscribe_resp(void *json_object, void *param);
|
||||
|
||||
typedef struct {
|
||||
char *group;
|
||||
bool subscribed;
|
||||
} neu_json_get_driver_subscribe_resp_group_t;
|
||||
|
||||
typedef struct {
|
||||
char * driver;
|
||||
int n_group;
|
||||
neu_json_get_driver_subscribe_resp_group_t *groups;
|
||||
} neu_json_get_driver_subscribe_resp_driver_t;
|
||||
|
||||
typedef struct {
|
||||
int n_driver;
|
||||
neu_json_get_driver_subscribe_resp_driver_t *drivers;
|
||||
} neu_json_get_driver_subscribe_resp_t;
|
||||
|
||||
int neu_json_encode_get_driver_subscribe_resp(void *json_object, void *param);
|
||||
|
||||
typedef struct {
|
||||
char *group;
|
||||
char *app;
|
||||
@@ -118,6 +139,7 @@ typedef struct {
|
||||
char *static_tags;
|
||||
} neu_json_subscribe_req_t;
|
||||
|
||||
int neu_json_encode_subscribe_req(void *json_object, void *param);
|
||||
int neu_json_decode_subscribe_req(char *buf, neu_json_subscribe_req_t **result);
|
||||
void neu_json_decode_subscribe_req_free(neu_json_subscribe_req_t *req);
|
||||
|
||||
@@ -127,6 +149,7 @@ typedef struct {
|
||||
char *driver;
|
||||
} neu_json_unsubscribe_req_t;
|
||||
|
||||
int neu_json_encode_unsubscribe_req(void *json_object, void *param);
|
||||
int neu_json_decode_unsubscribe_req(char * buf,
|
||||
neu_json_unsubscribe_req_t **result);
|
||||
void neu_json_decode_unsubscribe_req_free(neu_json_unsubscribe_req_t *req);
|
||||
|
||||
@@ -137,6 +137,20 @@ void neu_json_decode_add_node_req_free(neu_json_add_node_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
int neu_json_encode_del_node_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_del_node_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "name",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->name,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_del_node_req(char *buf, neu_json_del_node_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -416,6 +430,25 @@ void neu_json_decode_get_nodes_resp_free(neu_json_get_nodes_resp_t *resp)
|
||||
}
|
||||
}
|
||||
|
||||
int neu_json_encode_update_node_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_update_node_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "name",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->name,
|
||||
},
|
||||
{
|
||||
.name = "new_name",
|
||||
.t = NEU_JSON_INT,
|
||||
.v.val_str = req->new_name,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_update_node_req(char * buf,
|
||||
neu_json_update_node_req_t **result)
|
||||
{
|
||||
@@ -468,6 +501,25 @@ void neu_json_decode_update_node_req_free(neu_json_update_node_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
int neu_json_encode_node_ctl_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_node_ctl_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
},
|
||||
{
|
||||
.name = "cmd",
|
||||
.t = NEU_JSON_INT,
|
||||
.v.val_int = req->cmd,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_node_ctl_req(char *buf, neu_json_node_ctl_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -516,6 +568,23 @@ void neu_json_decode_node_ctl_req_free(neu_json_node_ctl_req_t *req)
|
||||
free(req);
|
||||
}
|
||||
|
||||
int neu_json_encode_node_setting_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_node_setting_req_t *req = param;
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
if (0 == ret) {
|
||||
ret = neu_json_load_key(json_object, "params", req->setting, true);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_node_setting_req(char * buf,
|
||||
neu_json_node_setting_req_t **result)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef struct {
|
||||
char *name;
|
||||
} neu_json_del_node_req_t;
|
||||
|
||||
int neu_json_encode_del_node_req(void *json_object, void *param);
|
||||
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);
|
||||
|
||||
@@ -104,6 +105,7 @@ typedef struct {
|
||||
char *new_name;
|
||||
} neu_json_update_node_req_t;
|
||||
|
||||
int neu_json_encode_update_node_req(void *json_object, void *param);
|
||||
int neu_json_decode_update_node_req(char * buf,
|
||||
neu_json_update_node_req_t **result);
|
||||
void neu_json_decode_update_node_req_free(neu_json_update_node_req_t *req);
|
||||
@@ -113,6 +115,7 @@ typedef struct {
|
||||
int64_t cmd;
|
||||
} neu_json_node_ctl_req_t;
|
||||
|
||||
int neu_json_encode_node_ctl_req(void *json_object, void *param);
|
||||
int neu_json_decode_node_ctl_req(char *buf, neu_json_node_ctl_req_t **result);
|
||||
void neu_json_decode_node_ctl_req_free(neu_json_node_ctl_req_t *req);
|
||||
|
||||
@@ -121,6 +124,7 @@ typedef struct {
|
||||
char *setting;
|
||||
} neu_json_node_setting_req_t;
|
||||
|
||||
int neu_json_encode_node_setting_req(void *json_object, void *param);
|
||||
int neu_json_decode_node_setting_req(char * buf,
|
||||
neu_json_node_setting_req_t **result);
|
||||
void neu_json_decode_node_setting_req_free(neu_json_node_setting_req_t *req);
|
||||
|
||||
@@ -29,6 +29,22 @@
|
||||
|
||||
#include "neu_json_plugin.h"
|
||||
|
||||
int neu_json_encode_add_plugin_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_add_plugin_req_t *req = param;
|
||||
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "library",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->library,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_add_plugin_req(char * buf,
|
||||
neu_json_add_plugin_req_t **result)
|
||||
{
|
||||
@@ -86,6 +102,22 @@ void neu_json_decode_add_plugin_req_free(neu_json_add_plugin_req_t *req)
|
||||
free(req);
|
||||
}
|
||||
|
||||
int neu_json_encode_del_plugin_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_add_plugin_req_t *req = param;
|
||||
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "library",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->library,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_del_plugin_req(char * buf,
|
||||
neu_json_del_plugin_req_t **result)
|
||||
{
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct {
|
||||
|
||||
typedef neu_json_add_plugin_req_t neu_json_update_plugin_req_t;
|
||||
|
||||
int neu_json_encode_add_plugin_req(void *json_object, void *param);
|
||||
int neu_json_decode_add_plugin_req(char * buf,
|
||||
neu_json_add_plugin_req_t **result);
|
||||
void neu_json_decode_add_plugin_req_free(neu_json_add_plugin_req_t *req);
|
||||
@@ -47,6 +48,7 @@ typedef struct {
|
||||
char *plugin;
|
||||
} neu_json_del_plugin_req_t;
|
||||
|
||||
int neu_json_encode_del_plugin_req(void *json_object, void *param);
|
||||
int neu_json_decode_del_plugin_req(char * buf,
|
||||
neu_json_del_plugin_req_t **result);
|
||||
void neu_json_decode_del_plugin_req_free(neu_json_del_plugin_req_t *req);
|
||||
|
||||
@@ -262,6 +262,43 @@ void neu_json_decode_tag_array_fini(neu_json_tag_array_t *arr)
|
||||
free(arr->tags);
|
||||
}
|
||||
|
||||
int neu_json_encode_add_tags_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_add_tags_req_t *req = param;
|
||||
void * tag_array = neu_json_array();
|
||||
if (NULL == tag_array) {
|
||||
return -1;
|
||||
}
|
||||
neu_json_tag_array_t arr = {
|
||||
.len = req->n_tag,
|
||||
.tags = req->tags,
|
||||
};
|
||||
ret = neu_json_encode_tag_array(tag_array, &arr);
|
||||
if (0 != ret) {
|
||||
neu_json_encode_free(tag_array);
|
||||
return ret;
|
||||
}
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->group,
|
||||
},
|
||||
{
|
||||
.name = "tags",
|
||||
.t = NEU_JSON_OBJECT,
|
||||
.v.val_object = tag_array,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_add_tags_req(char *buf, neu_json_add_tags_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -534,6 +571,38 @@ void neu_json_decode_gtag_array_fini(neu_json_gtag_array_t *arr)
|
||||
free(arr->gtags);
|
||||
}
|
||||
|
||||
int neu_json_encode_add_gtags_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_add_gtags_req_t *req = param;
|
||||
neu_json_gtag_array_t gtag_array = { .len = req->n_group,
|
||||
.gtags = req->groups };
|
||||
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
|
||||
json_t *groups_json = json_array();
|
||||
if (NULL == groups_json ||
|
||||
0 != json_object_set_new(json_object, "groups", groups_json)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
neu_json_encode_gtag_array(groups_json, >ag_array);
|
||||
|
||||
for (int i = 0; i < req->n_group; i++) {
|
||||
free(req->groups[i].group);
|
||||
free(req->groups[i].tags);
|
||||
}
|
||||
free(req->groups);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_add_gtags_req(char *buf, neu_json_add_gtags_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -630,6 +699,44 @@ int neu_json_encode_au_gtags_resp(void *json_object, void *param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_encode_del_tags_req(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_del_tags_req_t * req = param;
|
||||
void * tag_array = neu_json_array();
|
||||
neu_json_del_tags_req_name_t *p_name = req->tags;
|
||||
for (int i = 0; i < req->n_tags; i++) {
|
||||
neu_json_elem_t tag_elems[] = {
|
||||
{
|
||||
.name = NULL,
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = *p_name,
|
||||
},
|
||||
};
|
||||
tag_array = neu_json_encode_array_value(tag_array, tag_elems,
|
||||
NEU_JSON_ELEM_SIZE(tag_elems));
|
||||
p_name++;
|
||||
}
|
||||
neu_json_elem_t req_elems[] = { {
|
||||
.name = "node",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->node,
|
||||
},
|
||||
{
|
||||
.name = "group",
|
||||
.t = NEU_JSON_STR,
|
||||
.v.val_str = req->group,
|
||||
},
|
||||
{
|
||||
.name = "tags",
|
||||
.t = NEU_JSON_OBJECT,
|
||||
.v.val_object = tag_array,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, req_elems,
|
||||
NEU_JSON_ELEM_SIZE(req_elems));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_del_tags_req(char *buf, neu_json_del_tags_req_t **result)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef struct {
|
||||
neu_json_tag_t *tags;
|
||||
} neu_json_add_tags_req_t;
|
||||
|
||||
int neu_json_encode_add_tags_req(void *json_object, void *param);
|
||||
int neu_json_decode_add_tags_req(char *buf, neu_json_add_tags_req_t **result);
|
||||
void neu_json_decode_add_tags_req_free(neu_json_add_tags_req_t *req);
|
||||
|
||||
@@ -101,6 +102,7 @@ typedef struct {
|
||||
neu_json_gtag_t *groups;
|
||||
} neu_json_add_gtags_req_t;
|
||||
|
||||
int neu_json_encode_add_gtags_req(void *json_object, void *param);
|
||||
int neu_json_decode_add_gtags_req(char *buf, neu_json_add_gtags_req_t **result);
|
||||
void neu_json_decode_add_gtags_req_free(neu_json_add_gtags_req_t *req);
|
||||
|
||||
@@ -120,6 +122,7 @@ typedef struct {
|
||||
neu_json_del_tags_req_name_t *tags;
|
||||
} neu_json_del_tags_req_t;
|
||||
|
||||
int neu_json_encode_del_tags_req(void *json_object, void *param);
|
||||
int neu_json_decode_del_tags_req(char *buf, neu_json_del_tags_req_t **result);
|
||||
void neu_json_decode_del_tags_req_free(neu_json_del_tags_req_t *req);
|
||||
|
||||
|
||||
@@ -510,4 +510,41 @@ int neu_http_post_otel_trace(uint8_t *data, int len)
|
||||
nng_http_conn_close(conn);
|
||||
nng_aio_free(aio);
|
||||
return status;
|
||||
}
|
||||
|
||||
int neu_http_response_file(nng_aio *aio, void *data, size_t len,
|
||||
const char *disposition)
|
||||
{
|
||||
nng_http_res *res = NULL;
|
||||
int rv = 0;
|
||||
|
||||
if (((rv = nng_http_res_alloc(&res)) != 0) ||
|
||||
((rv = nng_http_res_set_status(res, NNG_HTTP_STATUS_OK)) != 0) ||
|
||||
((rv = nng_http_res_set_header(res, "Content-Type",
|
||||
"application/octet-stream")) != 0) ||
|
||||
((rv = nng_http_res_set_header(res, "Content-Disposition",
|
||||
disposition)) != 0) ||
|
||||
((rv = nng_http_res_set_header(res, "Access-Control-Allow-Origin",
|
||||
"*")) != 0) ||
|
||||
((rv = nng_http_res_set_header(res, "Access-Control-Allow-Methods",
|
||||
"POST,GET,PUT,DELETE,OPTIONS")) != 0) ||
|
||||
((rv = nng_http_res_set_header(res, "Access-Control-Allow-Headers",
|
||||
"*")) != 0) ||
|
||||
((rv = nng_http_res_set_header(res, "Access-Control-Expose-Headers",
|
||||
"Content-Disposition")) != 0) ||
|
||||
((rv = nng_http_res_copy_data(res, data, len)) != 0)) {
|
||||
nng_http_res_free(res);
|
||||
nng_aio_finish(aio, rv);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
nng_http_req *nng_req = nng_aio_get_input(aio, 0);
|
||||
nlog_notice("%s %s [%d]", nng_http_req_get_method(nng_req),
|
||||
nng_http_req_get_uri(nng_req), NNG_HTTP_STATUS_OK);
|
||||
|
||||
nng_aio_set_output(aio, 0, res);
|
||||
nng_aio_finish(aio, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -525,6 +525,10 @@ static int decode_object(json_t *root, neu_json_elem_t *ele)
|
||||
ele->t = NEU_JSON_ARRAY_BOOL;
|
||||
break;
|
||||
}
|
||||
if (json_is_object(value)) {
|
||||
ele->t = NEU_JSON_OBJECT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (json_is_object(ob)) {
|
||||
ele->t = NEU_JSON_OBJECT;
|
||||
|
||||
@@ -610,6 +610,39 @@ class TestHttp:
|
||||
response = api.get_status()
|
||||
assert 200 == response.status_code
|
||||
|
||||
@description(given="running neuron", when="get node or group by filter", then="success")
|
||||
def test_get_node_or_group_by_filter(self):
|
||||
node_1 = "test1"
|
||||
node_2 = "test2"
|
||||
group_1 = "abcd1"
|
||||
group_2 = "abdc2"
|
||||
api.add_node_check(node_1, 'Modbus TCP')
|
||||
api.add_node_check(node_2, 'Modbus TCP')
|
||||
api.add_group_check(node_1, group_1, 1000)
|
||||
api.add_group_check(node_1, group_2, 1000)
|
||||
api.add_group_check(node_2, group_1, 1000)
|
||||
# api.add_group_check(node_2, group_2, 1000)
|
||||
|
||||
response = api.get_nodes(1)
|
||||
assert 2 == len(response.json()["nodes"])
|
||||
response = api.get_nodes(1, group="dc")
|
||||
assert 1 == len(response.json()["nodes"])
|
||||
response = api.get_nodes(1, group="ab")
|
||||
assert 2 == len(response.json()["nodes"])
|
||||
response = api.get_nodes(1, group="test")
|
||||
assert 2 == len(response.json()["nodes"])
|
||||
response = api.get_nodes(1, group="test1")
|
||||
assert 1 == len(response.json()["nodes"])
|
||||
response = api.get_nodes(1, group="1234")
|
||||
assert 0 == len(response.json()["nodes"])
|
||||
response = api.get_group(node=node_1)
|
||||
assert 2 == len(response.json()["groups"])
|
||||
response = api.get_group(node=node_1, group="1")
|
||||
assert 1 == len(response.json()["groups"])
|
||||
response = api.get_group(node=node_2)
|
||||
assert 1 == len(response.json()["groups"])
|
||||
|
||||
|
||||
@description(given="running neuron", when="test jwt error", then="failed")
|
||||
def test_jwt_err(self):
|
||||
response = api.change_password(new_password='123456', jwt='invalid')
|
||||
@@ -629,3 +662,5 @@ class TestHttp:
|
||||
|
||||
response = api.delete_virtual_license(jwt='invalid')
|
||||
assert 404 == response.status_code
|
||||
|
||||
|
||||
|
||||
+12
-4
@@ -79,8 +79,11 @@ def del_node(node, jwt=config.default_jwt):
|
||||
return requests.delete(url=config.BASE_URL + '/api/v2/node', headers={"Authorization": jwt}, json={"name": node})
|
||||
|
||||
|
||||
def get_nodes(type, jwt=config.default_jwt):
|
||||
return requests.get(url=config.BASE_URL + '/api/v2/node', headers={"Authorization": jwt}, params={"type": type})
|
||||
def get_nodes(type, jwt=config.default_jwt, group=""):
|
||||
if group == "":
|
||||
return requests.get(url=config.BASE_URL + '/api/v2/node', headers={"Authorization": jwt}, params={"type": type})
|
||||
else:
|
||||
return requests.get(url=config.BASE_URL + '/api/v2/node?group=' + group, headers={"Authorization": jwt}, params={"type": type})
|
||||
|
||||
|
||||
@gen_check
|
||||
@@ -124,8 +127,13 @@ def update_group(node, group, new_name="", interval=0):
|
||||
|
||||
|
||||
@gen_check
|
||||
def get_group(node=""):
|
||||
return requests.get(url=config.BASE_URL + f'/api/v2/group?node={node}', headers={"Authorization": config.default_jwt})
|
||||
def get_group(node="", group=""):
|
||||
if group == "":
|
||||
return requests.get(url=config.BASE_URL + f'/api/v2/group?node={node}', headers={"Authorization": config.default_jwt})
|
||||
else:
|
||||
return requests.get(url=config.BASE_URL + f'/api/v2/group?node={node}&group={group}', headers={"Authorization": config.default_jwt})
|
||||
|
||||
|
||||
|
||||
|
||||
@gen_check
|
||||
|
||||
Reference in New Issue
Block a user