diff --git a/include/neuron/define.h b/include/neuron/define.h index 5dba71b0..40f342b8 100644 --- a/include/neuron/define.h +++ b/include/neuron/define.h @@ -65,6 +65,7 @@ extern int default_log_level; extern bool disable_jwt; extern char host_port[32]; +extern char g_status[32]; typedef enum neu_plugin_kind { NEU_PLUGIN_KIND_STATIC = 0, diff --git a/plugins/restful/handle.c b/plugins/restful/handle.c index 82128c05..69aa9c5e 100644 --- a/plugins/restful/handle.c +++ b/plugins/restful/handle.c @@ -516,6 +516,12 @@ static struct neu_http_handler rest_handlers[] = { .url = "/api/v2/metrics", .value.handler = handle_get_metric, }, + { + .method = NEU_HTTP_METHOD_GET, + .type = NEU_HTTP_HANDLER_FUNCTION, + .url = "/api/v2/status", + .value.handler = handle_status, + }, }; void neu_rest_handler(const struct neu_http_handler **handlers, uint32_t *size) diff --git a/plugins/restful/normal_handle.c b/plugins/restful/normal_handle.c index 03b290af..5078da72 100644 --- a/plugins/restful/normal_handle.c +++ b/plugins/restful/normal_handle.c @@ -328,3 +328,22 @@ void handle_get_plugin_schema(nng_aio *aio) free(buf); free(schema_path); } + +void handle_status(nng_aio *aio) +{ + char *result = NULL; + + NEU_VALIDATE_JWT(aio); + + int ret = neu_asprintf(&result, "{\"status\":\"%s\"}", g_status); + + if (ret < 0) { + NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, { + neu_http_response(aio, error_code.error, result_error); + }); + return; + } + + neu_http_response(aio, 0, result); + free(result); +} diff --git a/plugins/restful/normal_handle.h b/plugins/restful/normal_handle.h index 05135f0a..6856140e 100644 --- a/plugins/restful/normal_handle.h +++ b/plugins/restful/normal_handle.h @@ -26,5 +26,6 @@ void handle_ping(nng_aio *aio); void handle_login(nng_aio *aio); void handle_password(nng_aio *aio); void handle_get_plugin_schema(nng_aio *aio); +void handle_status(nng_aio *aio); #endif \ No newline at end of file diff --git a/src/core/manager.c b/src/core/manager.c index d21a6652..58f57888 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -123,6 +123,8 @@ neu_manager_t *neu_manager_create() manager->timestamp_lev_manager = 0; + strncpy(g_status, "loading", sizeof(g_status)); + neu_metrics_init(); start_static_adapter(manager, DEFAULT_DASHBOARD_PLUGIN_NAME); @@ -155,6 +157,7 @@ neu_manager_t *neu_manager_create() manager->timer_timestamp = neu_event_add_timer(manager->events, timestamp_timer_param); + strncpy(g_status, "ready", sizeof(g_status)); nlog_notice("manager start"); return manager; } diff --git a/src/main.c b/src/main.c index 3402c1ec..c16a4512 100644 --- a/src/main.c +++ b/src/main.c @@ -41,6 +41,7 @@ zlog_category_t * neuron = NULL; bool disable_jwt = false; int default_log_level = ZLOG_LEVEL_NOTICE; char host_port[32] = { 0 }; +char g_status[32] = { 0 }; int64_t global_timestamp = 0; diff --git a/tests/ft/http_api/test_http_api.py b/tests/ft/http_api/test_http_api.py index 9fab2d74..e38cd7e6 100644 --- a/tests/ft/http_api/test_http_api.py +++ b/tests/ft/http_api/test_http_api.py @@ -127,12 +127,13 @@ global_config_del_modbus = { ] } + 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 200 == response.status_code assert error.NEU_ERR_SUCCESS == response.json()['error'] response = api.get_global_config() @@ -163,7 +164,7 @@ class TestHttp: assert config_data['settings'][0]['node'] == 'mqtt' response = api.put_global_config(json=global_config_del_modbus) - assert 200 == response.status_code + assert 200 == response.status_code assert error.NEU_ERR_SUCCESS == response.json()['error'] response = api.get_global_config() @@ -191,7 +192,7 @@ class TestHttp: @description(given="running neuron", when="get subscribe info", then="should success") def test_get_subscribe_info(self): app = 'MQTT-1' - params = {'topic':'/neuron/test'} + params = {'topic': '/neuron/test'} driver_1 = 'modbus-01' driver_2 = 'modbus-02' group_1 = 'group-01' @@ -212,7 +213,8 @@ class TestHttp: # match all drivers response = api.get_subscribe_group(app, driver='modbus') assert 200 == response.status_code - groups = sorted(response.json()['groups'], key=lambda g: (g['driver'], g['group'])) + groups = sorted(response.json()['groups'], key=lambda g: ( + g['driver'], g['group'])) assert len(groups) == 4 assert groups[0]['driver'] == driver_1 assert groups[0]['group'] == group_1 @@ -226,7 +228,8 @@ class TestHttp: # match one driver response = api.get_subscribe_group(app, driver=driver_1) assert 200 == response.status_code - groups = sorted(response.json()['groups'], key=lambda g: (g['driver'], g['group'])) + groups = sorted(response.json()['groups'], key=lambda g: ( + g['driver'], g['group'])) assert len(groups) == 2 assert groups[0]['driver'] == driver_1 assert groups[0]['group'] == group_1 @@ -241,7 +244,8 @@ class TestHttp: # match all groups response = api.get_subscribe_group(app, group='group') assert 200 == response.status_code - groups = sorted(response.json()['groups'], key=lambda g: (g['driver'], g['group'])) + groups = sorted(response.json()['groups'], key=lambda g: ( + g['driver'], g['group'])) assert len(groups) == 4 assert groups[0]['driver'] == driver_1 assert groups[0]['group'] == group_1 @@ -255,7 +259,8 @@ class TestHttp: # match one group response = api.get_subscribe_group(app, group=group_1) assert 200 == response.status_code - groups = sorted(response.json()['groups'], key=lambda g: (g['driver'], g['group'])) + groups = sorted(response.json()['groups'], key=lambda g: ( + g['driver'], g['group'])) assert len(groups) == 2 assert groups[0]['driver'] == driver_1 assert groups[0]['group'] == group_1 @@ -268,15 +273,19 @@ class TestHttp: assert len(response.json()['groups']) == 0 # match driver and group - response = api.get_subscribe_group(app, driver=driver_1, group=group_1) + response = api.get_subscribe_group( + app, driver=driver_1, group=group_1) assert 200 == response.status_code - groups = sorted(response.json()['groups'], key=lambda g: (g['driver'], g['group'])) + groups = sorted(response.json()['groups'], key=lambda g: ( + g['driver'], g['group'])) assert len(groups) == 1 assert groups[0]['driver'] == driver_1 assert groups[0]['group'] == group_1 - response = api.get_subscribe_group(app, driver=driver_2, group=group_2) + response = api.get_subscribe_group( + app, driver=driver_2, group=group_2) assert 200 == response.status_code - groups = sorted(response.json()['groups'], key=lambda g: (g['driver'], g['group'])) + groups = sorted(response.json()['groups'], key=lambda g: ( + g['driver'], g['group'])) assert len(groups) == 1 assert groups[0]['driver'] == driver_2 assert groups[0]['group'] == group_2 @@ -307,16 +316,23 @@ class TestHttp: response = api.get_version() assert 200 == response.status_code + @description(given="running neuron", when="get status", then="success") + def test_get_status(self): + response = api.get_status() + 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') + 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') + response = api.post_ndriver_map( + ndriver='mqtt', driver='modbus', group='group') assert 400 == response.status_code response = api.get_ndriver_map(ndriver='mqtt') @@ -325,17 +341,19 @@ class TestHttp: 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 + 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.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') + response = api.delete_ndriver_map( + ndriver='mqtt', driver='modbus', group='group') assert 200 == response.status_code @description(given="running neuron", when="test jwt error", then="failed") @@ -356,4 +374,4 @@ class TestHttp: assert 404 == response.status_code response = api.delete_virtual_license(jwt='invalid') - assert 404 == response.status_code \ No newline at end of file + assert 404 == response.status_code diff --git a/tests/ft/neuron/api.py b/tests/ft/neuron/api.py index 6aff9d45..c5b39ba0 100644 --- a/tests/ft/neuron/api.py +++ b/tests/ft/neuron/api.py @@ -151,12 +151,14 @@ def read_tags(node, group, sync=False, query=None): body["query"] = query return requests.post(url=config.BASE_URL + "/api/v2/read", headers={"Authorization": config.default_jwt}, json=body) + def read_tags_paginate(node, group, sync=False, query=None): body = {"node": node, "group": group, "sync": sync} if query: body["query"] = query return requests.post(url=config.BASE_URL + "/api/v2/read/paginate", headers={"Authorization": config.default_jwt}, json=body) + def read_tag(node, group, tag, sync=False): response = read_tags(node, group, sync, query={"name": tag}) assert 200 == response.status_code @@ -343,6 +345,10 @@ def get_version(): return requests.get(url=config.BASE_URL + "/api/v2/version", headers={"Authorization": config.default_jwt}) +def get_status(): + return requests.get(url=config.BASE_URL + "/api/v2/status", headers={"Authorization": config.default_jwt}) + + def post_ndriver_map(ndriver, driver, group): return requests.post(url=config.BASE_URL + "/api/v2/ndriver/map", headers={"Authorization": config.default_jwt}, json={"ndriver": ndriver, "driver": driver, "group": group})