# Copyright(c) 2015-2023 ACCESS CO., LTD. All rights reserved.
use Croma
defmodule AntikytheraCore.Handler.SystemInfoExporter do
defmodule AccessToken do
alias AntikytheraCore.Path, as: CorePath
@table_name AntikytheraCore.Ets.SystemCache.table_name()
@key :system_info_access_token
defun init() :: :ok do
token = File.read!(CorePath.system_info_access_token_path())
:ets.insert(@table_name, {@key, token})
:ok
end
# This is public just to be used in testgear's test
defun get() :: String.t() do
:ets.lookup_element(@table_name, @key, 2)
end
defun with_valid_token(req :: :cowboy_req.req(), f :: (() -> :cowboy_req.req())) ::
{:ok, :cowboy_req.req(), nil} do
valid_token = get()
req2 =
case :cowboy_req.header("authorization", req) do
^valid_token -> f.()
_ -> :cowboy_req.reply(404, req)
end
{:ok, req2, nil}
end
end
defmodule Versions do
@behaviour :cowboy_handler
@impl :cowboy_handler
defun init(req :: :cowboy_req.req(), nil) :: {:ok, :cowboy_req.req(), nil} do
AccessToken.with_valid_token(req, fn ->
body =
Application.started_applications()
|> Enum.sort()
|> Enum.map_join("\n", fn {name, _desc, v} -> "#{name} #{v}" end)
:cowboy_req.reply(200, %{}, body, req)
end)
end
end
defmodule Upgradability do
@behaviour :cowboy_handler
@impl :cowboy_handler
defun init(req :: :cowboy_req.req(), nil) :: {:ok, :cowboy_req.req(), nil} do
AccessToken.with_valid_token(req, fn ->
upgradability = :sys.get_state(AntikytheraCore.VersionUpgradeTaskQueue).enabled?
:cowboy_req.reply(200, %{}, "#{upgradability}", req)
end)
end
end
defmodule ErrorCount do
alias Antikythera.Time
alias AntikytheraCore.ErrorCountsAccumulator
@behaviour :cowboy_handler
@impl :cowboy_handler
defun init(_req :: :cowboy_req.req(), _initial_state :: :total | :per_otp_app) ::
{:ok, :cowboy_req.req(), nil} do
req, :total ->
AccessToken.with_valid_token(req, fn ->
reply(req, ErrorCountsAccumulator.get_total())
end)
req, :per_otp_app ->
AccessToken.with_valid_token(req, fn ->
with_otp_app_name(req, fn otp_app_name ->
reply(req, ErrorCountsAccumulator.get(otp_app_name))
end)
end)
end
defunp with_otp_app_name(
%{bindings: %{otp_app_name: s}} = req :: :cowboy_req.req(),
f :: (atom() -> :cowboy_req.req())
) :: :cowboy_req.req() do
try do
String.to_existing_atom(s)
rescue
ArgumentError -> nil
end
|> case do
nil -> :cowboy_req.reply(404, req)
otp_app_name -> f.(otp_app_name)
end
end
defunp reply(req :: :cowboy_req.req(), pairs :: ErrorCountsAccumulator.results()) ::
:cowboy_req.req() do
body = Enum.map_join(pairs, "\n", fn {t, n} -> Time.to_iso_timestamp(t) <> " #{n}" end)
:cowboy_req.reply(200, %{}, body, req)
end
end
end