diff --git a/apps/iot/include/iot.hrl b/apps/iot/include/iot.hrl index 633a746..90c48bc 100644 --- a/apps/iot/include/iot.hrl +++ b/apps/iot/include/iot.hrl @@ -65,7 +65,7 @@ -define(PUSH_SERVICE_CONFIG, 16#04). -define(PUSH_INVOKE, 16#05). --define(PUSH_TASK_LOG, 16#05). +-define(PUSH_TASK_LOG, 16#06). %% 缓存数据库表 -record(kv, { diff --git a/apps/iot/src/http/service_handler.erl b/apps/iot/src/http/service_handler.erl index 295533c..f37bb55 100644 --- a/apps/iot/src/http/service_handler.erl +++ b/apps/iot/src/http/service_handler.erl @@ -13,48 +13,43 @@ %% API -export([handle_request/4]). -%% 保存服务配置 -handle_request("POST", "/service/set_config", _, #{<<"uuid">> := UUID, <<"service_id">> := ServiceId, <<"config_json">> := ConfigJson, <<"last_edit_user">> := LastEditUser}) - when is_binary(ServiceId), is_binary(ConfigJson), is_integer(LastEditUser) -> - lager:debug("[service_handler] set_service_config service_id: ~p, config_json: ~p, last_edit_user:~p", [ServiceId, ConfigJson, LastEditUser]), - - case iot_host:get_pid(UUID) of - undefined -> - {ok, 200, iot_util:json_error(404, <<"host not found">>)}; - Pid when is_pid(Pid) -> - case service_config_model:update(ServiceId, UUID, ConfigJson, LastEditUser) of - ok -> - {ok, 200, iot_util:json_data(<<"success">>)}; - {error, Reason} -> - lager:debug("[service_handler] set_config service_id: ~p, get error: ~p", [ServiceId, Reason]), - {ok, 200, iot_util:json_error(-1, <<"set service config failed">>)} - end - end; - -%% 下发config.json +%% 下发config.json, 微服务接受后,保存服务配置 handle_request("POST", "/service/push_config", _, - PostParams = #{<<"uuid">> := UUID, <<"service_id">> := ServiceId, <<"config_json">> := ConfigJson, <<"timeout">> := Timeout0}) + #{<<"uuid">> := UUID, <<"service_id">> := ServiceId, <<"last_edit_user">> := LastEditUser, <<"config_json">> := ConfigJson, <<"timeout">> := Timeout0}) when is_binary(UUID), is_binary(ServiceId), is_binary(ConfigJson), is_integer(Timeout0) -> - lager:debug("[http_host_handler] async_service_config body is: ~p", [PostParams]), - case iot_host:get_pid(UUID) of - undefined -> - {ok, 200, iot_util:json_error(404, <<"host not found">>)}; - Pid when is_pid(Pid) -> - Timeout = Timeout0 * 1000, - case iot_host:async_service_config(Pid, ServiceId, ConfigJson, Timeout) of - {ok, Ref} -> - case iot_host:await_reply(Ref, Timeout) of - {ok, Result} -> - {ok, 200, iot_util:json_data(Result)}; - {error, Reason} -> - {ok, 200, iot_util:json_error(400, Reason)} - end; - {error, Reason} when is_binary(Reason) -> - {ok, 200, iot_util:json_error(400, Reason)} - end + %% 检查ConfigJson是否是合法的json字符串 + case iot_util:is_json(ConfigJson) of + true -> + case iot_host:get_pid(UUID) of + undefined -> + {ok, 200, iot_util:json_error(-1, <<"host not found">>)}; + Pid when is_pid(Pid) -> + Timeout = Timeout0 * 1000, + case iot_host:async_service_config(Pid, ServiceId, ConfigJson, Timeout) of + {ok, Ref} -> + case iot_host:await_reply(Ref, Timeout) of + {ok, Result} -> + %% 更新配置信息到数据库 + case service_config_model:update(ServiceId, UUID, ConfigJson, LastEditUser) of + ok -> + {ok, 200, iot_util:json_data(Result)}; + {error, Reason} -> + lager:debug("[service_handler] set_config service_id: ~p, get error: ~p", [ServiceId, Reason]), + {ok, 200, iot_util:json_error(-1, <<"set service config failed">>)} + end; + {error, Reason} -> + {ok, 200, iot_util:json_error(-1, Reason)} + end; + {error, Reason} when is_binary(Reason) -> + {ok, 200, iot_util:json_error(-1, Reason)} + end + end; + false -> + {ok, 200, iot_util:json_error(-1, <<"config is invalid json">>)} end; +%% 获取服务配置信息 handle_request("GET", "/service/get_config", #{<<"service_id">> := ServiceId}, _) when is_binary(ServiceId) -> case service_config_model:get_config(ServiceId) of error -> @@ -100,7 +95,7 @@ handle_request("POST", "/service/start", _, #{<<"uuid">> := UUID, <<"service_id" undefined -> {ok, 200, iot_util:json_error(404, <<"host not found">>)}; Pid when is_pid(Pid) -> - case iot_host:deploy_service(Pid, TaskId, ServiceId, TarUrl) of + case iot_host:start_service(Pid, ServiceId) of {ok, Ref} -> case iot_host:await_reply(Ref, 5000) of {ok, Result} -> @@ -113,6 +108,26 @@ handle_request("POST", "/service/start", _, #{<<"uuid">> := UUID, <<"service_id" end end; +%% 停止服务 +handle_request("POST", "/service/stop", _, #{<<"uuid">> := UUID, <<"service_id">> := ServiceId}) when is_binary(UUID), is_binary(ServiceId) -> + case iot_host:get_pid(UUID) of + undefined -> + {ok, 200, iot_util:json_error(404, <<"host not found">>)}; + Pid when is_pid(Pid) -> + case iot_host:stop_service(Pid, ServiceId) of + {ok, Ref} -> + case iot_host:await_reply(Ref, 5000) of + {ok, Result} -> + {ok, 200, iot_util:json_data(Result)}; + {error, Reason} -> + {ok, 200, iot_util:json_error(400, Reason)} + end; + {error, Reason} when is_binary(Reason) -> + {ok, 200, iot_util:json_error(400, Reason)} + end + end; + +%% 远程调用微服务, 返回值的格式为json handle_request("POST", "/service/invoke", _, #{<<"uuid">> := UUID, <<"service_id">> := ServiceId, <<"payload">> := Payload, <<"timeout">> := Timeout0}) when is_binary(UUID), is_binary(ServiceId), is_binary(Payload), is_integer(Timeout0) -> diff --git a/apps/iot/src/iot_util.erl b/apps/iot/src/iot_util.erl index 2b3404b..5267216 100644 --- a/apps/iot/src/iot_util.erl +++ b/apps/iot/src/iot_util.erl @@ -12,9 +12,20 @@ %% API -export([timestamp/0, number_format/2, current_time/0, timestamp_of_seconds/0, float_to_binary/2, int_format/2, file_uri/1]). -export([step/3, chunks/2, rand_bytes/1, uuid/0, md5/1, parse_mapper/1]). --export([json_data/1, json_error/2]). +-export([json_data/1, json_error/2, is_json/1]). -export([queue_limited_in/3, assert_call/2, assert/2]). +-spec is_json(Json :: term()) -> boolean(). +is_json(Json) when is_binary(Json) -> + case catch jiffy:decode(Json, [return_maps]) of + Result when is_list(Result) orelse is_map(Result) -> + true; + _ -> + false + end; +is_json(_Json) -> + false. + %% 时间,精确到毫秒 timestamp() -> {Mega, Seconds, Micro} = os:timestamp(),