defmodule Jellyfish.Client do
@moduledoc """
Defines a `t:Jellyfish.Client.t/0`.
By default, Mint adapter for [Tesla](https://github.com/elixir-tesla/tesla) is used to make HTTP requests, but it can be changed:
```
# config.exs
config :jellyfish_server_sdk, tesla_adapter: Tesla.Adapter.Hackney
# mix.exs
defp deps do
[
{:hackney, "~> 1.10"}
]
end
```
For the list of supported Tesla adapters refer to [Tesla docs](https://hexdocs.pm/tesla/readme.html#adapters).
"""
alias Jellyfish.Utils
@enforce_keys [
:http_client
]
defstruct @enforce_keys
@type t :: %__MODULE__{
http_client: Tesla.Client.t()
}
@typedoc """
Options needed to open connection to Jellyfish server.
* `:server_address` - address of the Jellyfish server instance.
* `:server_api_token` - token used for authorizing HTTP requests and WebSocket connection.
It's the same token as the one configured in Jellyfish.
* `:secure?` - if `true`, use HTTPS and WSS instead of HTTP and WS, `false` by default.
When an option is not explicily passed, value set in `config.exs` is used:
```
# in config.exs
config :jellyfish_server_sdk,
server_address: "localhost:5002",
server_api_token: "your-jellyfish-token",
secure?: true
```
"""
@type connection_options :: [
server_address: String.t(),
server_api_token: String.t(),
secure?: boolean()
]
@doc """
Creates a new instance of `t:Jellyfish.Client.t/0`.
For information about options, see `t:connection_options/0`.
"""
@spec new(connection_options()) :: t()
def new(opts \\ []) do
{address, api_token, secure?} = Utils.get_options_or_defaults(opts)
address = if secure?, do: "https://#{address}", else: "http://#{address}"
adapter = Application.get_env(:jellyfish_server_sdk, :tesla_adapter, Tesla.Adapter.Mint)
middleware = [
{Tesla.Middleware.BaseUrl, address},
{Tesla.Middleware.BearerAuth, token: api_token},
Tesla.Middleware.JSON
]
http_client = Tesla.client(middleware, adapter)
%__MODULE__{http_client: http_client}
end
@doc """
Updates Jellyfish address.
When running Jellyfish in a cluster, user has to
manually update Jellyfish address after creating a room.
See also `Jellyfish.Room.create/2`.
"""
@spec update_address(t(), String.t()) :: t()
def update_address(client, new_address) do
Utils.check_prefixes(new_address)
Map.update!(
client,
:http_client,
&Map.update!(&1, :pre, fn pre_list ->
Enum.map(pre_list, fn
{Tesla.Middleware.BaseUrl, :call, [old_address]} ->
[protocol | _] = String.split(old_address, ":")
{Tesla.Middleware.BaseUrl, :call, ["#{protocol}://#{new_address}"]}
other ->
other
end)
end)
)
end
end