Skip to content

Commit

Permalink
[#44] Introduce Primus/WS transfer configuration at run-time
Browse files Browse the repository at this point in the history
  • Loading branch information
Joseph Yiasemides committed May 28, 2018
1 parent 527bd15 commit 2d1938a
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 3 deletions.
35 changes: 35 additions & 0 deletions README.md
Expand Up @@ -58,6 +58,41 @@ If you want to run it on the local host then the procedure is as simple as: `_bu
**Note:** executables must be built on the platform (OS and architecture) they are destined for under the project's current configuration.
Other options are possible (see `https://hexdocs.pm/distillery/getting-started.html`).

## Configuration

Executables are built with a configuration as described above.
However the Primus/WebSocket transfer is configurable at run-time through a JSON configuration.
To configure this supply a path to a JSON file with the `transfer_config_overlay` key/value.
The following is an extract from [config/test.exs](config/test.exs):

```Elixir
config :poa_agent,
transfer_config_overlay: "config/transfer_overlay.json"
```

A corresponding example is provided in `config/transfer_overlay.json`:

```JSON
{
"POAAgent":{
"transfers":[
{
"id":"node_integration",
"address":"ws://localhost:3000/api",
"identifier":"elixirNodeJSIntegration",
"name":"Elixir-NodeJS-Integration",
"secret":"Fr00b5",
"contact":"a@b.c"
}
]
}
}

```

The file can reside anywhere on the machine that the Elixir executable has access to.
The key/value pairs in the JSON configuration will replace the defaults specified in the Elixir configuration (i.e. `config/{dev,test,prod}.exs`).

## Coverage

To get an HTML coverage report on your own machine try `env MIX_ENV=test mix coveralls.html` then open `cover/excoveralls.html`.
Expand Down
3 changes: 3 additions & 0 deletions config/test.exs
@@ -1,5 +1,8 @@
use Mix.Config

config :poa_agent,
transfer_config_overlay: "config/transfer_overlay.json"

config :ethereumex,
url: "http://localhost:8545"

Expand Down
14 changes: 14 additions & 0 deletions config/transfer_overlay.json
@@ -0,0 +1,14 @@
{
"POAAgent":{
"transfers":[
{
"id":"node_integration",
"address":"ws://localhost:3000/api",
"identifier":"elixirNodeJSIntegration",
"name":"Elixir-NodeJS-Integration",
"secret":"Fr00b5",
"contact":"a@b.c"
}
]
}
}
50 changes: 50 additions & 0 deletions lib/poa_agent/configuration.ex
@@ -0,0 +1,50 @@
defmodule POAAgent.Configuration do
@moduledoc false

def transfers do
elixir_config = Application.fetch_env!(:poa_agent, :transfers)
case Application.fetch_env(:poa_agent, :transfer_config_overlay) do
:error ->
elixir_config
{:ok, path} when is_binary(path) ->
path
|> File.read!()
|> Jason.decode!()
|> transfers(elixir_config)
end
end

def transfers(_, []) do
[]
end

def transfers(overlay, default) do
overlay
|> Kernel.get_in(["POAAgent", "transfers"])
|> Kernel.hd()
|> merge_overlay_into_config(default)
end

defp merge_overlay_into_config(overlay, [{id, module_name, default}]) do
keys = [
"address",
"identifier",
"name",
"secret",
"contact"
]
POAAgent.Plugins.Transfers.WebSocket.Primus = module_name
^id = String.to_existing_atom(Map.fetch!(overlay, "id"))
restricted = Map.take(overlay, keys)
want = to_keyword(restricted)
final = Keyword.merge(default, want)
[{id, module_name, final}]
end

defp to_keyword(x) do
f = fn {k, v} ->
{String.to_existing_atom(k), v}
end
Enum.into(x, [], f)
end
end
5 changes: 2 additions & 3 deletions lib/poa_agent/plugins/transfers/supervisor.ex
Expand Up @@ -9,7 +9,7 @@ defmodule POAAgent.Plugins.Transfers.Supervisor do
import Supervisor.Spec

# create the children from the config file
transfers = Application.get_env(:poa_agent, :transfers)
transfers = POAAgent.Configuration.transfers()

children = for {name, module, args} <- transfers do
worker(module, [%{name: name, args: args}])
Expand All @@ -18,5 +18,4 @@ defmodule POAAgent.Plugins.Transfers.Supervisor do
opts = [strategy: :one_for_one]
supervise(children, opts)
end

end
end
41 changes: 41 additions & 0 deletions test/poa_agent/configuration_test.exs
@@ -0,0 +1,41 @@
defmodule POAAgent.ConfigurationTest do
use ExUnit.Case

test "transfer configuration overlay and default merge" do
default = [
{:node_integration, POAAgent.Plugins.Transfers.WebSocket.Primus, [
address: "ws://localhost:3000/api",
identifier: "elixirNodeJSIntegration",
name: "Elixir-NodeJS-Integration",
secret: "",
contact: "mymail@mail.com"
]
}
]
overlay = %{"POAAgent" =>
%{"transfers" =>
[
%{"address" => "ws://localhost:3000/api",
"contact" => "a@b.c",
"id" => "node_integration",
"identifier" => "elixirNodeJSIntegration",
"name" => "Elixir-NodeJS-Integration",
"secret" => "Fr00b5"
}
]
}
}

assert POAAgent.Configuration.transfers(overlay, default) == [
{:node_integration, POAAgent.Plugins.Transfers.WebSocket.Primus,
[address: "ws://localhost:3000/api",
contact: "a@b.c",
identifier: "elixirNodeJSIntegration",
name: "Elixir-NodeJS-Integration",
secret: "Fr00b5"
]
}
]
assert POAAgent.Configuration.transfers(overlay, []) == []
end
end

0 comments on commit 2d1938a

Please sign in to comment.