Packages
commanded
1.1.0
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.0
1.3.1
1.3.0
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.1
1.0.0-rc.0
0.19.1
0.19.0
0.18.1
0.18.0
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.16.0-rc.1
0.16.0-rc.0
0.15.1
0.15.0
0.14.0
0.14.0-rc.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.5
0.8.4
0.8.3
0.8.1
0.8.0
0.7.1
0.6.2
0.6.1
0.6.0
0.4.0
0.3.1
0.3.0
0.2.1
0.2.0
0.1.0
Use Commanded to build your own Elixir applications following the CQRS/ES pattern.
Current section
Files
Jump to
Current section
Files
lib/commanded/middleware/extract_aggregate_identity.ex
defmodule Commanded.Middleware.ExtractAggregateIdentity do
@moduledoc """
An internal `Commanded.Middleware` that extracts the target aggregate's
identity from the command.
"""
@behaviour Commanded.Middleware
alias Commanded.Middleware.Pipeline
import Pipeline
def before_dispatch(%Pipeline{} = pipeline) do
with aggregate_uuid when aggregate_uuid not in [nil, ""] <- extract_aggregate_uuid(pipeline),
aggregate_uuid when is_binary(aggregate_uuid) <- identity_to_string(aggregate_uuid),
aggregate_uuid when is_binary(aggregate_uuid) <- prefix(aggregate_uuid, pipeline) do
assign(pipeline, :aggregate_uuid, aggregate_uuid)
else
nil ->
pipeline
|> respond({:error, :invalid_aggregate_identity})
|> halt()
{:error, _error} = response ->
pipeline
|> respond(response)
|> halt()
end
end
def after_dispatch(%Pipeline{} = pipeline), do: pipeline
def after_failure(%Pipeline{} = pipeline), do: pipeline
# Extract identity using a field in the command.
defp extract_aggregate_uuid(%Pipeline{command: command, identity: identity})
when is_atom(identity) do
Map.get(command, identity)
end
# Extract identity using a user defined function.
defp extract_aggregate_uuid(%Pipeline{command: command, identity: identity})
when is_function(identity, 1) do
identity.(command)
end
defp extract_aggregate_uuid(%Pipeline{}), do: {:error, :invalid_aggregate_identity}
# Attempt to convert the aggregate identity to a string via the `String.Chars` protocol.
defp identity_to_string(aggregate_uuid) do
try do
to_string(aggregate_uuid)
rescue
Protocol.UndefinedError ->
{:error, {:unsupported_aggregate_identity_type, aggregate_uuid}}
end
end
# No aggregate identity prefix.
defp prefix(aggregate_uuid, %Pipeline{identity_prefix: identity_prefix})
when identity_prefix in [nil, ""],
do: aggregate_uuid
# Extract identity prefix using a user defined function.
defp prefix(aggregate_uuid, %Pipeline{identity_prefix: identity_prefix})
when is_function(identity_prefix, 0) do
identity_prefix.() <> aggregate_uuid
end
# Identity prefix is a string to prepend to aggregate identity.
defp prefix(aggregate_uuid, %Pipeline{identity_prefix: identity_prefix})
when is_binary(identity_prefix),
do: identity_prefix <> aggregate_uuid
defp prefix(_aggregate_uuid, %Pipeline{}), do: {:error, :invalid_aggregate_identity_prefix}
end