69 lines
2.2 KiB
Elixir
69 lines
2.2 KiB
Elixir
defmodule MessageServer.MessageHandler do
|
|
require Logger
|
|
|
|
alias MessageServer.{
|
|
MessageRequest,
|
|
RemoteClient,
|
|
ServerRegistry,
|
|
Storage
|
|
}
|
|
|
|
@spec handle_message(MessageRequest.t()) :: :ok | {:error, String.t()}
|
|
def handle_message(%MessageRequest{from: from, to: to, message: message}) do
|
|
with {:ok, from_server} <- extract_server_id(from),
|
|
{:ok, to_server} <- extract_server_id(to),
|
|
:ok <- validate_sender_ownership(from_server),
|
|
:ok <- route_message(to_server, from, to, message) do
|
|
Logger.info("Message routed successfully from #{from} to #{to}")
|
|
:ok
|
|
else
|
|
{:error, reason} = error ->
|
|
Logger.warning("Message routing failed: #{reason}")
|
|
error
|
|
end
|
|
end
|
|
|
|
@spec extract_server_id(String.t()) :: {:ok, String.t()} | {:error, String.t()}
|
|
defp extract_server_id(user_id) do
|
|
case String.split(user_id, "-", parts: 2) do
|
|
[server_id, _user_part] -> {:ok, server_id}
|
|
_ -> {:error, "Invalid user ID format: #{user_id}"}
|
|
end
|
|
end
|
|
|
|
@spec validate_sender_ownership(String.t()) :: :ok | {:error, String.t()}
|
|
defp validate_sender_ownership(sender_server) do
|
|
local_server = ServerRegistry.get_server_id()
|
|
|
|
if sender_server == local_server do
|
|
:ok
|
|
else
|
|
{:error, "Cannot send messages on behalf of users from other servers"}
|
|
end
|
|
end
|
|
|
|
@spec route_message(String.t(), String.t(), String.t(), String.t()) ::
|
|
:ok | {:error, String.t()}
|
|
defp route_message(to_server, from, to, message) do
|
|
local_server = ServerRegistry.get_server_id()
|
|
|
|
if to_server == local_server do
|
|
handle_local_message(from, to, message)
|
|
else
|
|
handle_remote_message(to_server, from, to, message)
|
|
end
|
|
end
|
|
|
|
@spec handle_local_message(String.t(), String.t(), String.t()) :: :ok | {:error, String.t()}
|
|
defp handle_local_message(from, to, message) do
|
|
Storage.append_message(to, from, message)
|
|
end
|
|
|
|
@spec handle_remote_message(String.t(), String.t(), String.t(), String.t()) ::
|
|
:ok | {:error, String.t()}
|
|
defp handle_remote_message(to_server, from, to, message) do
|
|
payload = %MessageRequest{from: from, to: to, message: message}
|
|
RemoteClient.send_message_to_server(to_server, payload)
|
|
end
|
|
end
|