defmodule Bungee do @moduledoc """ Supervisor for Bungee """ use GenServer use Tesla plug(Tesla.Middleware.JSON) adapter(:hackney) alias Bungee.Request.Builder, as: RequestBuilder alias Bungee.Response.Validator, as: ResponseValidator alias Bungee.Response.Returner, as: ResponseReturner require Logger @spec handle_cast( {:save, index :: atom, type :: atom, request_options :: list, identifier :: binary, document :: map}, config :: %Bungee.Config{} ) :: {:noreply, %Bungee.Config{}} @spec handle_call( {action :: :save | :delete, index :: atom, type :: atom, request_options :: list, identifier :: binary, document :: map}, from :: {pid, any}, config :: %Bungee.Config{} ) :: {:reply, any, %Bungee.Config{}} @spec handle_call( {action :: :fetch | :fetch_by | :query, index :: atom, type :: atom, request_options :: list, identifier :: binary, document :: map}, from :: {pid, any}, config :: %Bungee.Config{} ) :: {:reply, any, %Bungee.Config{}} @doc """ Start a Bungee GenServer ``` config :bungee, :config, %{ uri: "http://localhost:9200", index: "bungee_index" } ``` """ def start_link(otp_app \\ :bungee) do Logger.info(fn -> "bungee: Starting Process ..." end) config = otp_app |> Application.get_env(:config) |> (fn map -> struct(Bungee.Config, map) end).() GenServer.start_link(__MODULE__, config, name: otp_app) end @doc """ """ def init(config) do Logger.info(fn -> "bungee: Configuration: #{inspect(config)}" end) {:ok, config} end @doc """ ASYNC We should do something with `?op_type=create`` """ def handle_cast( {:save, index, type, request_options, identifier, document}, config ) when is_map(document) do {_, :ok} = [] |> RequestBuilder.init(config) |> RequestBuilder.add_method(:post) |> RequestBuilder.add_index(index || config.index) |> RequestBuilder.add_type(type) |> RequestBuilder.add_identifier(identifier) |> RequestBuilder.add_request_options(request_options) |> RequestBuilder.add_document(document) |> RequestBuilder.encode_body() |> log_debug() |> request() |> ResponseValidator.response_ok?() {:noreply, config} end @doc """ """ def handle_call( {:save, index, type, request_options, identifier, document}, _from, config ) when is_map(document) do return = [] |> RequestBuilder.init(config) |> RequestBuilder.add_method(:post) |> RequestBuilder.add_index(index || config.index) |> RequestBuilder.add_type(type) |> RequestBuilder.add_identifier(identifier) |> RequestBuilder.add_request_options(request_options) |> RequestBuilder.add_document(document) |> RequestBuilder.encode_body() |> log_debug() |> request() |> ResponseValidator.response_ok?() |> ResponseReturner.return(identifier, document) {:reply, return, config} end @doc """ """ def handle_call( {:delete, index, type, request_options, identifier, _document}, _from, config ) do return = [] |> RequestBuilder.init(config) |> RequestBuilder.add_method(:delete) |> RequestBuilder.add_index(index || config.index) |> RequestBuilder.add_type(type) |> RequestBuilder.add_identifier(identifier) |> RequestBuilder.add_request_options(request_options) |> RequestBuilder.encode_body() |> log_debug() |> request() |> ResponseValidator.response_ok?() |> ResponseReturner.return(identifier, nil) {:reply, return, config} end def handle_call( {:fetch, index, type, request_options, identifier, module, _document}, _from, config ) do return = [] |> RequestBuilder.init(config) |> RequestBuilder.add_method(:get) |> RequestBuilder.add_index(index || config.index) |> RequestBuilder.add_type(type) |> RequestBuilder.add_identifier(identifier) |> RequestBuilder.add_request_options(request_options) |> RequestBuilder.encode_body() |> log_debug() |> request() |> ResponseValidator.response_ok?() |> ResponseReturner.return(identifier, nil, module) {:reply, return, config} end def handle_call( {:fetch_by, index, type, request_options, search_field, search_term, module}, _from, config ) do return = [] |> RequestBuilder.init(config) |> RequestBuilder.add_method(:post) |> RequestBuilder.add_index(index || config.index) |> RequestBuilder.add_type(type) |> RequestBuilder.add_search_parameters(search_field, search_term) |> RequestBuilder.add_request_options([search: true] ++ request_options) |> RequestBuilder.encode_body() |> log_debug() |> request() |> ResponseValidator.response_ok?() |> ResponseReturner.return(nil, module) {:reply, return, config} end def handle_call( {:query, index, type, request_options, query, module, _document}, _from, config ) do return = [] |> RequestBuilder.init(config) |> RequestBuilder.add_method(:get) |> RequestBuilder.add_index(index || config.index) |> RequestBuilder.add_type(type) |> RequestBuilder.add_query(query) |> RequestBuilder.add_request_options([search: true] ++ request_options) |> RequestBuilder.encode_body() |> log_debug() |> request() |> ResponseValidator.response_ok?() |> ResponseReturner.return(nil, module) {:reply, return, config} end defp log_debug(request) do Logger.debug(fn -> "Bungee Request: #{inspect(request)}" end) request end end