diff --git a/README.md b/README.md index 5626ecc..8cfed24 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,60 @@ -# BirdyChat +# BirdyChat Tech Challenge -To start your Phoenix server: +This repository implements BirdyChat tech challenge. -* Run `mix setup` to install and setup dependencies -* Start Phoenix endpoint with `mix phx.server` or inside IEx with `iex -S mix phx.server` +# Start here -Now you can visit [`localhost:4000`](http://localhost:4000) from your browser. +Firstly, check out this repository locally. +Then install required versions of Elixir and Erlang from .tool-versions. asdf-vm will pick them up automatically. +Then you run the test suite with `mix test`. +Then, a scripted demo release is prepared in the prod environment: -Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html). +``` +MIX_ENV=prod mix build_release +``` -## Learn more +Then you can run 3 servers connected to one another: -* Official website: https://www.phoenixframework.org/ -* Guides: https://hexdocs.pm/phoenix/overview.html -* Docs: https://hexdocs.pm/phoenix -* Forum: https://elixirforum.com/c/phoenix-forum -* Source: https://github.com/phoenixframework/phoenix +`_build/prod/rel/birdy_chat/bin/server_1` - runs at localhost:4001 +`_build/prod/rel/birdy_chat/bin/server_2` - runs at localhost:4002 +`_build/prod/rel/birdy_chat/bin/server_3` - runs at localhost:4003 + +Out of the box they communicate with one another. Send a json request to one of them and observe the results. Feel free to modify the examples below. + +### A local request: + +``` +curl --request POST \ + --url http://localhost:4001/api/messages \ + --header 'content-type: application/json' \ + --data '{"message":"123","to":"1-user","from":"1-user"}' +``` + +### A remote request: + +``` +curl --request POST \ + --url http://localhost:4001/api/messages \ + --header 'content-type: application/json' \ + --data '{"message":"123","to":"2-user","from":"1-user"}' +``` + +### A request to unknown server: + +``` +curl --request POST \ + --url http://localhost:4001/api/messages \ + --header 'content-type: application/json' \ + --data '{"message":"123","to":"4-user","from":"1-user"}' +``` + +Files are saved to `priv/messages`. + + +## Key rundown of technical details + +First and foremost, I tried to keep it as simple as possible - stick to know conventions, leverage existing libraries or frameworks, hence the usage of both Phoenix and Ecto - conventions they provide are understandable to pretty much any Elixir developer. + +All important modules are documented and there is a test suite that exacutes all known code paths. + +Servers authenticate with one another using Phoenix tokens. Servers communicate via HTTP using JSON. There were other options but I decided to use this one for reasons enumerated in documentation for BirdyChatWeb.Api.Server.Internal.Controller. diff --git a/lib/birdy_chat_web/api/server/internal/controller.ex b/lib/birdy_chat_web/api/server/internal/controller.ex index cdb9766..c368d5b 100644 --- a/lib/birdy_chat_web/api/server/internal/controller.ex +++ b/lib/birdy_chat_web/api/server/internal/controller.ex @@ -14,7 +14,7 @@ defmodule BirdyChatWeb.Api.Server.Internal.Controller do The endpoint is protected by simple authentication that requires the secret key of all servers being the same. It is good enough for a demo, but for any real application it would need to be - reconsidered. + reconsidered. HTTPS would be a non-negotiable requirement for any user-facing deployment. """ use BirdyChatWeb, :controller diff --git a/rel/overlays/bin/server.bat b/rel/overlays/bin/server.bat deleted file mode 100755 index f91dc6f..0000000 --- a/rel/overlays/bin/server.bat +++ /dev/null @@ -1,2 +0,0 @@ -set PHX_SERVER=true -call "%~dp0\birdy_chat" start diff --git a/rel/overlays/bin/server_1 b/rel/overlays/bin/server_1 index 4fbccde..a2ec8ca 100755 --- a/rel/overlays/bin/server_1 +++ b/rel/overlays/bin/server_1 @@ -6,7 +6,7 @@ cd -P -- "$(dirname -- "$0")" export SECRET_KEY_BASE=Yhmq6FzYQt4g5AFHfSdMBKKf4oRo4KRo703FK6b7RwmH5pXlyQNompUOF7/EEC5t export BIRDY_CHAT_PORT=4001 export BIRDY_CHAT_IDENTITY=1 -export BIRDY_CHAT_PEERS=2::http://localhost:4002 +export BIRDY_CHAT_PEERS="2::http://localhost:4002;3::http://localhost:4003" export PHX_SERVER=true export RELEASE_NAME=server_1 exec ./birdy_chat start diff --git a/rel/overlays/bin/server_2 b/rel/overlays/bin/server_2 index a565979..8572ff4 100755 --- a/rel/overlays/bin/server_2 +++ b/rel/overlays/bin/server_2 @@ -6,7 +6,7 @@ cd -P -- "$(dirname -- "$0")" export SECRET_KEY_BASE=Yhmq6FzYQt4g5AFHfSdMBKKf4oRo4KRo703FK6b7RwmH5pXlyQNompUOF7/EEC5t export BIRDY_CHAT_PORT=4002 export BIRDY_CHAT_IDENTITY=2 -export BIRDY_CHAT_PEERS=1::http://localhost:4001 +export BIRDY_CHAT_PEERS="1::http://localhost:4001g;3::http://localhost:4003" export PHX_SERVER=true export RELEASE_NAME=server_2 exec ./birdy_chat start diff --git a/rel/overlays/bin/server_3 b/rel/overlays/bin/server_3 new file mode 100755 index 0000000..21cb303 --- /dev/null +++ b/rel/overlays/bin/server_3 @@ -0,0 +1,12 @@ +#!/bin/sh +set -eu + +cd -P -- "$(dirname -- "$0")" + +export SECRET_KEY_BASE=Yhmq6FzYQt4g5AFHfSdMBKKf4oRo4KRo703FK6b7RwmH5pXlyQNompUOF7/EEC5t +export BIRDY_CHAT_PORT=4003 +export BIRDY_CHAT_IDENTITY=3 +export BIRDY_CHAT_PEERS="1::http://localhost:4001;2::http://localhost:4002" +export PHX_SERVER=true +export RELEASE_NAME=server_3 +exec ./birdy_chat start