Packages
avrora
0.18.0
0.30.2
0.30.1
0.30.0
0.29.2
0.29.1
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.2
0.24.1
0.24.0
0.23.0
0.22.0
0.21.1
0.21.0
0.20.0
0.19.0
0.18.1
0.18.0
0.17.0
0.16.0
0.15.0
0.14.1
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.1
0.9.0
0.8.1
0.8.0
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.1
0.3.0
0.2.2
0.2.1
0.2.0
0.1.1-beta
0.1.0-beta
An Elixir library for working with Avro messages conveniently. It supports local schema files and Confluent® schema registry.
Current section
Files
Jump to
Current section
Files
lib/avrora/client.ex
defmodule Avrora.Client do
@moduledoc """
Generates client module with isolated memory storage.
## Examples
defmodule MyClient do
use Avrora.Client,
schemas_path: Path.expand("./priv/schemas"),
registry_url: "https://registry.io"
end
It will expose `Avrora.Encoder` module functions and make `MyClient` module
identical to `Avrora` module, but isolated from it.
To start using `MyClient` follow the [Start cache process](README.md#start-cache-process),
add it to your supervision tree
children = [
MyClient
]
Supervisor.start_link(children, strategy: :one_for_one)
or start the process manually
{:ok, pid} = MyClient.start_link()
"""
@modules ~w(
schema
encoder
resolver
avro_schema_store
avro_decoder_options
codec/plain
codec/schema_registry
codec/object_container_file
storage/file
storage/memory
storage/registry
utils/registrar
)
@aliases ~w(
Codec
Config
Schema
Resolver
AvroDecoderOptions
Codec.Plain
Codec.SchemaRegistry
Codec.ObjectContainerFile
Storage.Registry
Storage.File
)
import Keyword, only: [get: 3]
defp personalize(definition, module: module) do
definition = Regex.replace(~r/defmodule Avrora\./, definition, "defmodule ")
~r/alias Avrora\.(.*)/
|> Regex.scan(definition)
|> Enum.reject(fn [_, m] -> !Enum.member?(@aliases, m) end)
|> Enum.reduce(definition, fn [als, mdl], dfn ->
Regex.replace(~r/#{als}(?=[[:cntrl:]])/, dfn, "alias #{module}.#{mdl}")
end)
end
defp generate!(definition, file: file) do
case Code.string_to_quoted(definition, file: file) do
{:ok, quoted} ->
quoted
{:error, {line, error, token}} ->
raise "error #{error} on line #{line} caused by #{inspect(token)}"
end
end
defmacro __using__(opts) do
module = __CALLER__.module |> Module.split() |> Enum.join(".")
modules =
@modules
|> Enum.map(fn name ->
file = Path.expand("./#{name}.ex", __DIR__)
file
|> File.read!()
|> personalize(module: module)
|> generate!(file: file)
end)
config =
quote do
defmodule Config do
@moduledoc false
def schemas_path, do: unquote(get(opts, :schemas_path, Path.expand("./priv/schemas")))
def registry_url, do: unquote(get(opts, :registry_url, nil))
def registry_auth, do: unquote(get(opts, :registry_auth, nil))
def registry_schemas_autoreg, do: unquote(get(opts, :registry_schemas_autoreg, true))
def convert_null_values, do: unquote(get(opts, :convert_null_values, true))
def convert_map_to_proplist, do: unquote(get(opts, :convert_map_to_proplist, false))
def names_cache_ttl, do: unquote(get(opts, :names_cache_ttl, :infinity))
def file_storage, do: :"Elixir.#{unquote(module)}.Storage.File"
def memory_storage, do: :"Elixir.#{unquote(module)}.Storage.Memory"
def registry_storage, do: :"Elixir.#{unquote(module)}.Storage.Registry"
def http_client, do: Avrora.HTTPClient
def ets_lib, do: :"Elixir.#{unquote(module)}.AvroSchemaStore"
def self, do: __MODULE__
end
end
quote location: :keep do
unquote(modules)
unquote(config)
use Supervisor
defdelegate decode(payload), to: :"Elixir.#{unquote(module)}.Encoder"
defdelegate encode(payload, opts), to: :"Elixir.#{unquote(module)}.Encoder"
defdelegate decode(payload, opts), to: :"Elixir.#{unquote(module)}.Encoder"
defdelegate extract_schema(payload), to: :"Elixir.#{unquote(module)}.Encoder"
def start_link(opts \\ []), do: Supervisor.start_link(__MODULE__, opts, name: __MODULE__)
@impl true
def init(_state \\ []) do
children = [
:"Elixir.#{unquote(module)}.AvroSchemaStore",
:"Elixir.#{unquote(module)}.Storage.Memory"
]
Supervisor.init(children, strategy: :one_for_all)
end
end
end
end