defmodule Ravix.Connection.ServerNode do @moduledoc """ State of a RavenDB connection executor node - store: Atom of the RavenDB Store, E.g: Ravix.Test.Store - url: URL of this node - port: port of this node - conn: TCP Connection State - protocol: http or https - database: For which database is this executor - cluster_tag: Tag of this node in the RavenDB cluster - settings: General node settings """ defstruct store: nil, url: nil, port: nil, client: nil, protocol: nil, database: nil, cluster_tag: nil, settings: nil alias Ravix.Connection.ServerNode alias Ravix.Connection.State, as: ConnectionState @type t :: %ServerNode{ store: atom(), url: String.t(), port: non_neg_integer(), protocol: atom(), database: String.t(), cluster_tag: String.t() | nil, settings: ServerNode.Settings.t() } def bootstrap(%ConnectionState{} = conn_state) do conn_state.urls |> Enum.map(fn url -> parsed_url = URI.parse(url) %ServerNode{ store: conn_state.store, url: parsed_url.host, port: parsed_url.port, protocol: String.to_atom(parsed_url.scheme), database: conn_state.database, settings: ServerNode.Settings.build(conn_state) } end) end def from_api_response(node_response, %ConnectionState{} = conn_state) do parsed_url = URI.new!(node_response["Url"]) %ServerNode{ store: conn_state.store, url: parsed_url.host, port: parsed_url.port, protocol: String.to_atom(parsed_url.scheme), database: node_response["Database"], cluster_tag: node_response["ClusterTag"], settings: ServerNode.Settings.build(conn_state) } end def node_id(%ServerNode{} = server_node), do: :crypto.hash(:sha256, server_node.url <> server_node.database) |> Base.encode16() |> String.downcase() @doc """ Helper method to build the base path for Database specific API requests """ @spec node_database_path(ServerNode.t()) :: String.t() def node_database_path(%ServerNode{} = server_node), do: "/databases/#{server_node.database}" @doc """ Node host and port """ @spec node_url(ServerNode.t()) :: String.t() def node_url(%ServerNode{} = node), do: "#{node.protocol}://#{node.url}:#{node.port}" defimpl String.Chars, for: Ravix.Connection.ServerNode do def to_string(nil) do "" end def to_string(node) do ServerNode.node_url(node) end end defmodule Settings do @moduledoc """ - http_client_name: Name of the Finch http client to use with this node, """ defstruct retry_on_stale: true, http_client_name: Ravix.Finch alias __MODULE__ @type t :: %__MODULE__{ retry_on_stale: boolean(), http_client_name: atom() } def build(conn_state) do %Settings{ retry_on_stale: conn_state.retry_on_stale, http_client_name: conn_state.http_client_name } end end end