defmodule Wobserver.Web.Router.Api do @moduledoc ~S""" Main api router. Returns the following resources: - `/about` => `Wobserver.about/0`. - `/nodes` => `Wobserver.NodeDiscovery.discover/0`. Splits into the following paths: - `/system`, for all system information, handled by `Wobserver.Web.Router.System`. All paths also include the option of entering a node name before the path. """ use Wobserver.Web.Router.Base alias Wobserver.Allocator alias Wobserver.Page alias Wobserver.Table alias Wobserver.Util.Application alias Wobserver.Util.Process alias Wobserver.Util.Node.Discovery alias Wobserver.Util.Node.Remote alias Wobserver.Web.Router.Api alias Wobserver.Web.Router.System match "/nodes" do Discovery.discover() |> send_json_resp(conn) end match "/custom" do Page.list() |> send_json_resp(conn) end match "/about" do Wobserver.about() |> send_json_resp(conn) end get "/application/:app" do app |> String.downcase() |> String.to_atom() |> Application.info() |> send_json_resp(conn) end get "/application" do Application.list() |> send_json_resp(conn) end get "/process" do Process.list() |> send_json_resp(conn) end get "/process/:pid" do pid |> Process.info() |> send_json_resp(conn) end get "/ports" do Wobserver.Port.list() |> send_json_resp(conn) end get "/allocators" do Allocator.list() |> send_json_resp(conn) end get "/table" do Table.list() |> send_json_resp(conn) end get "/table/:table" do table |> Table.sanitize() |> Table.info(true) |> send_json_resp(conn) end forward("/system", to: System) match "/:node_name/*glob" do case glob do [] -> node_name |> String.to_atom() |> Page.call() |> send_json_resp(conn) # conn # |> send_resp(501, "Custom commands not implemented yet.") _ -> node_forward(node_name, conn, glob) end end match _ do conn |> send_resp(404, "Page not Found") end # Helpers defp node_forward(node_name, conn, glob) do case Discovery.find(node_name) do :local -> local_forward(conn, glob) {:remote, remote_node} -> remote_forward(remote_node, conn, glob) :unknown -> send_resp(conn, 404, "Node #{node_name} not Found") end end defp local_forward(conn, glob) do Plug.forward( var!(conn), var!(glob), Api, Api.init([]) ) end defp remote_forward(remote_node, conn, glob) do path = glob |> Enum.join() case Remote.api(remote_node, "/" <> path) do :error -> conn |> send_resp(500, "Node #{remote_node.name} not responding.") data -> conn |> put_resp_content_type("application/json") |> send_resp(200, data) end end end