summaryrefslogtreecommitdiff
path: root/src/flagd-ui/lib/flagd_ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/flagd-ui/lib/flagd_ui')
-rw-r--r--src/flagd-ui/lib/flagd_ui/application.ex43
-rw-r--r--src/flagd-ui/lib/flagd_ui/mailer.ex6
-rw-r--r--src/flagd-ui/lib/flagd_ui/storage.ex71
3 files changed, 120 insertions, 0 deletions
diff --git a/src/flagd-ui/lib/flagd_ui/application.ex b/src/flagd-ui/lib/flagd_ui/application.ex
new file mode 100644
index 0000000..732e4d0
--- /dev/null
+++ b/src/flagd-ui/lib/flagd_ui/application.ex
@@ -0,0 +1,43 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+defmodule FlagdUi.Application do
+ # See https://hexdocs.pm/elixir/Application.html
+ # for more information on OTP Applications
+ @moduledoc false
+
+ use Application
+
+ @impl true
+ def start(_type, _args) do
+ # Ensure inets is started before OpenTelemetry initialization
+ :ok = Application.ensure_started(:inets)
+
+ children = [
+ FlagdUiWeb.Telemetry,
+ {DNSCluster, query: Application.get_env(:flagd_ui, :dns_cluster_query) || :ignore},
+ {Phoenix.PubSub, name: FlagdUi.PubSub},
+ FlagdUi.Storage,
+ # Start a worker by calling: FlagdUi.Worker.start_link(arg)
+ # {FlagdUi.Worker, arg},
+ # Start to serve requests, typically the last entry
+ FlagdUiWeb.Endpoint
+ ]
+
+ OpentelemetryBandit.setup()
+ OpentelemetryPhoenix.setup(adapter: :bandit)
+
+ # See https://hexdocs.pm/elixir/Supervisor.html
+ # for other strategies and supported options
+ opts = [strategy: :one_for_one, name: FlagdUi.Supervisor]
+ Supervisor.start_link(children, opts)
+ end
+
+ # Tell Phoenix to update the endpoint configuration
+ # whenever the application is updated.
+ @impl true
+ def config_change(changed, _new, removed) do
+ FlagdUiWeb.Endpoint.config_change(changed, removed)
+ :ok
+ end
+end
diff --git a/src/flagd-ui/lib/flagd_ui/mailer.ex b/src/flagd-ui/lib/flagd_ui/mailer.ex
new file mode 100644
index 0000000..c22a862
--- /dev/null
+++ b/src/flagd-ui/lib/flagd_ui/mailer.ex
@@ -0,0 +1,6 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+defmodule FlagdUi.Mailer do
+ use Swoosh.Mailer, otp_app: :flagd_ui
+end
diff --git a/src/flagd-ui/lib/flagd_ui/storage.ex b/src/flagd-ui/lib/flagd_ui/storage.ex
new file mode 100644
index 0000000..eefcb13
--- /dev/null
+++ b/src/flagd-ui/lib/flagd_ui/storage.ex
@@ -0,0 +1,71 @@
+# Copyright The OpenTelemetry Authors
+# SPDX-License-Identifier: Apache-2.0
+
+defmodule FlagdUi.Storage do
+ @moduledoc """
+ Storage module. This module initializes a process as a separate GenServer
+ to linearize reads and writes preventing conflicts and last-writer-wins.
+ """
+
+ use GenServer
+ require Logger
+
+ @file_path Application.compile_env!(:flagd_ui, :storage_file_path)
+
+ def start_link(opts) do
+ name = Keyword.get(opts, :name, Storage)
+
+ GenServer.start_link(__MODULE__, %{}, name: name)
+ end
+
+ @impl true
+ def init(_) do
+ state = @file_path |> File.read!() |> Jason.decode!()
+ Logger.info("Read new state from file")
+
+ {:ok, state}
+ end
+
+ @impl true
+ def handle_call(:read, _from, state) do
+ {:reply, state, state}
+ end
+
+ @impl true
+ def handle_cast({:replace, json_string}, _) do
+ new_state = Jason.decode!(json_string)
+
+ write_state(json_string)
+
+ {:noreply, new_state}
+ end
+
+ @impl true
+ def handle_cast({:write, flag_name, flag_value}, state) do
+ new_state =
+ Map.update(state, "flags", %{}, fn flags ->
+ update_flag(flags, flag_name, flag_value)
+ end)
+
+ json_state = Jason.encode!(new_state, pretty: true)
+
+ write_state(json_state)
+
+ {:noreply, new_state}
+ end
+
+ defp update_flag(flags, flag_name, value) do
+ flags
+ |> Enum.map(fn
+ {flag, data} when flag == flag_name -> {flag, Map.replace(data, "defaultVariant", value)}
+ {flag, data} -> {flag, data}
+ end)
+ |> Map.new()
+ end
+
+ defp write_state(json_string) do
+ File.write!(@file_path, json_string)
+
+ Logger.info("Wrote new state to file")
+ end
+end