From a03ad825769e154400f32bb9114e26a6a57137e8 Mon Sep 17 00:00:00 2001 From: Mikael Fangel <34864484+MikaelFangel@users.noreply.github.com> Date: Wed, 29 May 2024 08:28:01 +0000 Subject: [PATCH] feat: add run_search (#13) * search_api: simplify using get search result * logpoint_api: add initial run_search function * logpoint_api: add missing s in success * logpoint_api: make run_search fail fast * logpoint_api: add doc and fix spec * version: bump minor --- README.md | 2 +- lib/logpoint_api.ex | 45 +++++++++++++++++++++++++++++++++++++++++++++ lib/search_api.ex | 7 +++---- mix.exs | 2 +- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index de6c441..d3e0668 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Elixir library implementing the [Logpoint API reference](https://docs.logpoint.c ```elixir def deps do [ - {:logpoint_api, github: "MikaelFangel/logpoint_api", tag: "v0.1.1"} + {:logpoint_api, github: "MikaelFangel/logpoint_api", tag: "v0.2.1"} ] end ``` diff --git a/lib/logpoint_api.ex b/lib/logpoint_api.ex index 57ff874..6fa838a 100644 --- a/lib/logpoint_api.ex +++ b/lib/logpoint_api.ex @@ -1,6 +1,9 @@ defmodule LogpointApi do @moduledoc false + alias LogpointApi.SearchApi.Query + alias LogpointApi.SearchApi + defmodule Credential do @typedoc """ Struct representing credentials used for authorization. @@ -8,4 +11,46 @@ defmodule LogpointApi do @type t :: %__MODULE__{username: String.t(), secret_key: String.t()} defstruct [:username, :secret_key] end + + @doc """ + Run a search query. + """ + @spec run_search(String.t(), Credential.t(), Query.t()) :: map() + def run_search(ip, credential, %Query{} = query) do + {:ok, %{"success" => true} = search_info} = SearchApi.get_search_id(ip, credential, query) + search_id = Map.get(search_info, "search_id") + + SearchApi.get_search_result(ip, credential, search_id) + |> handle_search_result(ip, credential, search_id, query) + end + + defp handle_search_result({:ok, %{"final" => true} = result}, _, _, _, _), do: result + + defp handle_search_result( + {:ok, %{"final" => false, "success" => true}}, + ip, + credential, + search_id, + query + ) do + result = SearchApi.get_search_result(ip, credential, search_id) + + # Wait before retrying. + :timer.sleep(1000) + + handle_search_result(result, ip, credential, search_id, query) + end + + defp handle_search_result( + {:ok, %{"final" => false, "success" => false}}, + ip, + credential, + _, + query + ) do + # Wait before recreating the search. + :timer.sleep(1000) + + run_search(ip, credential, query) + end end diff --git a/lib/search_api.ex b/lib/search_api.ex index 493cffe..20504fd 100644 --- a/lib/search_api.ex +++ b/lib/search_api.ex @@ -4,7 +4,6 @@ defmodule LogpointApi.SearchApi do """ alias LogpointApi.Credential - alias LogpointApi.SearchApi.{Query, SearchID} @allowed_types ["user_preference", "loginspects", "logpoint_repos", "devices", "livesearches"] @@ -77,10 +76,10 @@ defmodule LogpointApi.SearchApi do @doc """ Retrieve the search result of a specific search id. """ - @spec get_search_result(String.t(), Credential.t(), SearchID.t()) :: + @spec get_search_result(String.t(), Credential.t(), String.t()) :: {:ok, map()} | {:error, String.t()} - def get_search_result(ip, credential, %SearchID{} = search_id), - do: get_search_logs(ip, credential, search_id) + def get_search_result(ip, credential, search_id), + do: get_search_logs(ip, credential, %SearchID{search_id: search_id}) @doc false @spec make_request(String.t(), String.t(), String.t()) :: {:ok, map()} | {:error, String.t()} diff --git a/mix.exs b/mix.exs index 923ee3e..1fbd90a 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule LogpointApi.MixProject do def project do [ app: :logpoint_api, - version: "0.1.1", + version: "0.2.1", elixir: "~> 1.15", start_permanent: Mix.env() == :prod, deps: deps(),