Add src/hk_api_search_h.erl
Browse files- src/hk_api_search_h.erl +77 -0
src/hk_api_search_h.erl
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
%%%-------------------------------------------------------------------
|
| 2 |
+
%%% @doc `/search' API domain.
|
| 3 |
+
%%%
|
| 4 |
+
%%% POST /api/search start a job (async, returns job_id immediately)
|
| 5 |
+
%%% GET /api/search list jobs (current stage/iteration each)
|
| 6 |
+
%%% GET /api/search/:id describe one job's current stage
|
| 7 |
+
%%% GET /api/search/:id/result final result if `done'; 202 (pending) otherwise
|
| 8 |
+
%%%
|
| 9 |
+
%%% Progress between "started" and "result ready" is observed via
|
| 10 |
+
%%% the `search.*' events on the event stream, per the pipeline's
|
| 11 |
+
%%% event-per-stage requirement -- this handler does not poll or
|
| 12 |
+
%%% block waiting for the pipeline itself.
|
| 13 |
+
%%% @end
|
| 14 |
+
%%%-------------------------------------------------------------------
|
| 15 |
+
-module(hk_api_search_h).
|
| 16 |
+
|
| 17 |
+
-export([init/2]).
|
| 18 |
+
|
| 19 |
+
init(Req0 = #{method := <<"POST">>}, collection) ->
|
| 20 |
+
RequestId = hk_api_util:request_id(Req0),
|
| 21 |
+
{ok, Body, Req1} = hk_api_util:read_json_body(Req0),
|
| 22 |
+
OwnerAgentId = maps:get(<<"owner_agent_id">>, Body, undefined),
|
| 23 |
+
Query = maps:get(<<"query">>, Body, <<>>),
|
| 24 |
+
MaxIterations = maps:get(<<"max_iterations">>, Body, 3),
|
| 25 |
+
Req = hk_api_util:run_operation(search_start, RequestId, fun() ->
|
| 26 |
+
case hk_search:start(OwnerAgentId, Query, #{max_iterations => MaxIterations}) of
|
| 27 |
+
{ok, JobId} -> {ok, {search_job, JobId}, #{job_id => JobId}};
|
| 28 |
+
{error, Reason} -> {error, Reason}
|
| 29 |
+
end
|
| 30 |
+
end, Req1),
|
| 31 |
+
{ok, Req, collection};
|
| 32 |
+
|
| 33 |
+
init(Req0 = #{method := <<"GET">>}, collection) ->
|
| 34 |
+
Jobs = [describe_or_skip(Id) || {Id, _Pid} <- hk_search_registry:list_jobs()],
|
| 35 |
+
Req = hk_api_util:reply_json(200, #{jobs => [M || {true, M} <- Jobs]}, Req0),
|
| 36 |
+
{ok, Req, collection};
|
| 37 |
+
|
| 38 |
+
init(Req0 = #{method := <<"GET">>}, item) ->
|
| 39 |
+
JobId = cowboy_req:binding(id, Req0),
|
| 40 |
+
Req = case hk_search_registry:lookup(JobId) of
|
| 41 |
+
{ok, Pid} ->
|
| 42 |
+
{ok, Job} = hk_search_job:describe(Pid),
|
| 43 |
+
hk_api_util:reply_json(200, hk_schema:to_map(Job), Req0);
|
| 44 |
+
{error, not_found} ->
|
| 45 |
+
hk_api_util:reply_error(404, job_not_found, Req0)
|
| 46 |
+
end,
|
| 47 |
+
{ok, Req, item};
|
| 48 |
+
|
| 49 |
+
init(Req0 = #{method := <<"GET">>}, result) ->
|
| 50 |
+
JobId = cowboy_req:binding(id, Req0),
|
| 51 |
+
Req = case hk_search_registry:lookup(JobId) of
|
| 52 |
+
{ok, Pid} ->
|
| 53 |
+
case hk_search_job:await_result(Pid, 300) of
|
| 54 |
+
{ok, Result} -> hk_api_util:reply_json(200, Result, Req0);
|
| 55 |
+
{error, pending} -> hk_api_util:reply_json(202, #{status => pending}, Req0);
|
| 56 |
+
{error, Reason} -> hk_api_util:reply_error(422, Reason, Req0)
|
| 57 |
+
end;
|
| 58 |
+
{error, not_found} ->
|
| 59 |
+
hk_api_util:reply_error(404, job_not_found, Req0)
|
| 60 |
+
end,
|
| 61 |
+
{ok, Req, result};
|
| 62 |
+
|
| 63 |
+
init(Req0, State) ->
|
| 64 |
+
Req = hk_api_util:reply_error(405, method_not_allowed, Req0),
|
| 65 |
+
{ok, Req, State}.
|
| 66 |
+
|
| 67 |
+
%%% internal
|
| 68 |
+
|
| 69 |
+
describe_or_skip(JobId) ->
|
| 70 |
+
case hk_search_registry:lookup(JobId) of
|
| 71 |
+
{ok, Pid} ->
|
| 72 |
+
case catch hk_search_job:describe(Pid) of
|
| 73 |
+
{ok, Job} -> {true, hk_schema:to_map(Job)};
|
| 74 |
+
_ -> false
|
| 75 |
+
end;
|
| 76 |
+
_ -> false
|
| 77 |
+
end.
|