Skip to content

Commit

Permalink
add http api ft
Browse files Browse the repository at this point in the history
  • Loading branch information
hxy7yx committed Nov 22, 2023
1 parent 7d671ea commit 0367220
Show file tree
Hide file tree
Showing 8 changed files with 257 additions and 117 deletions.
9 changes: 0 additions & 9 deletions plugins/restful/handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,6 @@ static struct neu_http_handler cors_handler[] = {
{
.url = "/api/v2/password",
},
{
.url = "/api/v2/logs",
},
{
.url = "/api/v2/log/level",
},
Expand Down Expand Up @@ -366,12 +363,6 @@ static struct neu_http_handler rest_handlers[] = {
.url = "/api/v2/node/state",
.value.handler = handle_get_node_state,
},
{
.method = NEU_HTTP_METHOD_GET,
.type = NEU_HTTP_HANDLER_FUNCTION,
.url = "/api/v2/logs",
.value.handler = handle_logs_files,
},
{
.method = NEU_HTTP_METHOD_PUT,
.type = NEU_HTTP_HANDLER_FUNCTION,
Expand Down
104 changes: 0 additions & 104 deletions plugins/restful/log_handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,70 +42,6 @@
#include "log_handle.h"
#include "utils/utarray.h"

void handle_logs_files(nng_aio *aio)
{
void * data = NULL;
size_t len = 0;
int rv = 0;

NEU_VALIDATE_JWT(aio);

/* check whether the neuron directory exists */
rv = access("../neuron", F_OK);
if (0 != rv) {
nlog_error("The neuron directory does not exists");
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_NOT_EXIST, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}

rv = system("rm -rf /tmp/neuron_debug.tar.gz");
nlog_warn("remove old neuron_debug.tar.gz, rv: %d", rv);
/* tar the neuron directory */
rv = system("tar -zcvf /tmp/neuron_debug.tar.gz "
"--exclude='persistence/neuron.lic' ../neuron");
if (rv == -1) {
nlog_error("failed to create neuron_debug.tar.gz, rv: %d", rv);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, {
neu_http_response(aio, error_code.error, result_error);
});
return;
} else {
if (WIFEXITED(rv)) {
if (WEXITSTATUS(rv) < 0) {
nlog_error("failed to create neuron_debug.tar.gz, rv: %d",
WEXITSTATUS(rv));
NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}
} else {
nlog_error("failed to create neuron_debug.tar.gz, rv: %d",
WEXITSTATUS(rv));
NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}
}

rv = read_file("/tmp/neuron_debug.tar.gz", &data, &len);
if (0 != rv) {
NEU_JSON_RESPONSE_ERROR(
rv, { neu_http_response(aio, error_code.error, result_error); });
return;
}

/* handle http response */
rv = neu_http_response_file(aio, data, len,
"attachment; filename=neuron_debug.tar.gz");

free(data);
nlog_notice("download neuron_debug.tar.gz, ret: %d", rv);
}

void handle_log_level(nng_aio *aio)
{
neu_plugin_t *plugin = neu_rest_get_plugin();
Expand Down Expand Up @@ -156,44 +92,4 @@ void handle_log_level(nng_aio *aio)
}
}
})
}

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);
}
3 changes: 0 additions & 3 deletions plugins/restful/log_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
#include <nng/nng.h>

// void handle_get_log(nng_aio *aio);
void handle_logs_files(nng_aio *aio);
void handle_log_level(nng_aio *aio);

int read_file(const char *file_name, void **datap, size_t *lenp);

#endif
14 changes: 14 additions & 0 deletions tests/ft/driver/test_modbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,20 @@ def test_read_tag_length_exceeds_250(self, param):
node=param[0], group='group', tag=hold_string_l1[0]['name'])
assert 'b' == api.read_tag(
node=param[0], group='group', tag=hold_string_l2[0]['name'])

@description(given="created modbus node ,groups and tags", when="write/read gtags", then="write/read success")
def test_write_read_gtags(self, param):
modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags" : [{"tag": "hold_uint16", "value": 1}, {"tag": "hold_string", "value": 'hello'},
{"tag": "coil_bit_1", "value": 1}, {"tag": "hold_double_decimal", "value": 513.11}, {"tag": "hold_bytes", "value": [0x1, 0x2, 0x3, 0x4]}]},
{"group": "group1", "tags" : [{"tag": "hold_int16", "value": 1}]}]}
response = api.write_gtags(json=modbus_write_gtags)
assert 200 == response.status_code
assert error.NEU_ERR_SUCCESS == response.json()['error']
time.sleep(1.0)
assert 1 == api.read_tag(
node=param[0], group='group', tag=hold_uint16[0]['name'])
assert 1 == api.read_tag(
node=param[0], group='group1', tag=hold_int16[0]['name'])

@description(given="created modbus device_error_test node/tag", when="read tag", then="read failed")
def test_read_modbus_device_err(self, param):
Expand Down
3 changes: 3 additions & 0 deletions tests/ft/http_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import sys

sys.path.append("tests/ft")
199 changes: 199 additions & 0 deletions tests/ft/http_api/test_http_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import neuron.api as api
import neuron.error as error
import neuron.config as config
from neuron.common import *

hold_int16 = [{"name": "hold_int16", "address": "1!400001",
"attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}]

global_config = {
"nodes": [
{
"plugin": "MQTT",
"name": "mqtt"
},
{
"plugin": "Modbus TCP",
"name": "modbus"
}
],
"groups": [
{
"driver": "modbus",
"group": "group",
"tag_count": 1,
"interval": 100
}
],
"tags": [
{
"tags": [
{
"type": 3,
"name": "hold_int16",
"attribute": 3,
"precision": 0,
"decimal": 0.0,
"address": "1!400001",
"description": ""
}
],
"driver": "modbus",
"group": "group"
}
],
"subscriptions": [
{
"groups": [
{
"driver": "modbus",
"group": "group"
}
],
"app": "mqtt"
}
],
"settings": [
{
"node": "mqtt",
"params": {
"client-id": "neuron_aBcDeF",
"qos": 0,
"format": 0,
"write-req-topic": "/neuron/mqtt/write/req",
"write-resp-topic": "/neuron/mqtt/write/resp",
"offline-cache": False,
"cache-sync-interval": 100,
"host": "broker.emqx.io",
"port": 1883,
"username": "",
"password": "",
"ssl": False
}
},
{
"node": "modbus",
"params": {
"connection_mode": 0,
"transport_mode": 0,
"interval": 0,
"host": "127.0.0.1",
"port": 502,
"timeout": 3000,
"max_retries": 2
}
}
]
}

class TestHttp:

@description(given="running neuron", when="add driver/app node/group/tag, app subscribes driver group, and get global config", then="success")
def test_get_global_config(self):
response = api.put_global_config(json=global_config)
assert 200 == response.status_code
assert error.NEU_ERR_SUCCESS == response.json()['error']

response = api.get_global_config()
assert 200 == response.status_code

config_data = response.json()

assert 'nodes' in config_data
assert len(config_data['nodes']) == 2
assert config_data['nodes'][0]['plugin'] == 'MQTT'
assert config_data['nodes'][1]['plugin'] == 'Modbus TCP'

assert 'groups' in config_data
assert len(config_data['groups']) == 1
assert config_data['groups'][0]['driver'] == 'modbus'

assert 'tags' in config_data
assert len(config_data['tags']) == 1
assert config_data['tags'][0]['driver'] == 'modbus'
assert len(config_data['tags'][0]['tags']) == 1

assert 'subscriptions' in config_data
assert len(config_data['subscriptions']) == 1
assert config_data['subscriptions'][0]['app'] == 'mqtt'

assert 'settings' in config_data
assert len(config_data['settings']) == 2
assert config_data['settings'][0]['node'] == 'mqtt'

response = api.del_node_check(node='modbus')

response = api.get_global_config()
assert 200 == response.status_code

config_data = response.json()

assert 'nodes' in config_data
assert len(config_data['nodes']) == 1
assert config_data['nodes'][0]['plugin'] == 'MQTT'

assert 'groups' in config_data
assert len(config_data['groups']) == 0

assert 'tags' in config_data
assert len(config_data['tags']) == 0

assert 'subscriptions' in config_data
assert len(config_data['subscriptions']) == 0

assert 'settings' in config_data
assert len(config_data['settings']) == 1
assert config_data['settings'][0]['node'] == 'mqtt'

@description(given="running neuron", when="get mqtt shcema", then="success")
def test_get_plugin_schema(self):
response = api.get_plugin_schema(plugin='mqtt')
assert 200 == response.status_code

response = api.get_plugin_schema(plugin='modbus-tcp')
assert 200 == response.status_code

response = api.get_plugin_schema(plugin='invalid')
assert 404 == response.status_code
assert response.json()['status'] == 'error'

@description(given="running neuron", when="get plugin", then="success")
def test_get_plugin(self):
response = api.get_plugin()
assert 200 == response.status_code

@description(given="running neuron", when="get version", then="success")
def test_get_version(self):
response = api.get_version()
assert 200 == response.status_code

@description(given="running neuron", when="test ndriver", then="failed because it is not supported yet")
def test_ndriver(self):
api.add_node_check(node='modbus', plugin=config.PLUGIN_MODBUS_TCP)
api.add_group_check(node='modbus', group='group')
api.add_tags_check(node='modbus', group='group', tags=hold_int16)
response = api.subscribe_group(app='mqtt', driver='modbus', group='group')
assert 200 == response.status_code
assert error.NEU_ERR_SUCCESS == response.json()['error']

response = api.post_ndriver_map(ndriver='mqtt', driver='modbus', group='group')
assert 400 == response.status_code

response = api.get_ndriver_map(ndriver='mqtt')
assert 400 == response.status_code

ndriver_tag_param = {"ndriver": "mqtt", "driver": "modbus", "group": "group", "tags": [
{"name": "hold_int16", "params": {"address": "1!400002"}}]}
response = api.put_ndriver_tag_param(json=ndriver_tag_param)
assert 200 == response.status_code

ndriver_tag_info = {"ndriver": "mqtt", "driver": "modbus", "group": "group", "tags": [
{"name": "hold_int16", "address": "1!400002"}]}
response = api.put_ndriver_tag_info(json=ndriver_tag_info)
assert 200 == response.status_code

response = api.get_ndriver_tag(ndriver='mqtt', driver='modbus', group='group')
assert 200 == response.status_code

response = api.delete_ndriver_map(ndriver='mqtt', driver='modbus', group='group')
assert 200 == response.status_code
6 changes: 5 additions & 1 deletion tests/ft/log/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,8 @@ def test_change_node_log_level_only(self):
response = api.get_nodes_state('modbus-tcp-1')
assert 200 == response.status_code
assert "notice" == response.json()['neuron_core']
assert "info" == response.json()['log_level']
assert "info" == response.json()['log_level']

response = api.get_nodes_state(node='')
assert 200 == response.status_code
assert "notice" == response.json()['neuron_core']
Loading

0 comments on commit 0367220

Please sign in to comment.