defmodule LambdaBase do @moduledoc """ Documentation for LambdaBase. """ @doc """ Callback function. """ @callback handle(map(), map()) :: {:ok, String.t} | {:error, String.t} defmacro __using__(_opts) do quote do alias Util.Json alias Util.LambdaLogger @behaviour LambdaHandler def start() do context = System.get_env LambdaLogger.start(context |> log_level) HTTPoison.start() loop(context) end defp log_level(context) do context |> Map.get("LOG_LEVEL", "INFO") |> String.downcase |> String.to_atom end defp loop(context) do endpoint_uri = get_uri(context) case HTTPoison.get(endpoint_uri) do {:error, error} -> {:error, error.reason} {:ok, response} -> {_, request_id} = response.headers |> Enum.find(fn {x, _} -> x == "Lambda-Runtime-Aws-Request-Id" end) handle_event(response.body |> Json.decode, context, request_id) end loop(context) end defp handle_event(event, context, request_id) do LambdaLogger.debug(event) LambdaLogger.debug(context) LambdaLogger.debug(request_id) with( result <- handle(event, context) |> response |> Json.encode, endpoint_uri = post_uri(context, request_id), {:ok, response} <- HTTPoison.post(endpoint_uri, result) ) do LambdaLogger.debug(result) {:ok, response.body} else error -> LambdaLogger.error(error) {:error, "handle_error"} end end defp get_uri(context) do aws_lambda_runtime_api = context |> Map.get("AWS_LAMBDA_RUNTIME_API") "http://#{aws_lambda_runtime_api}/2018-06-01/runtime/invocation/next" end defp post_uri(context, request_id) do aws_lambda_runtime_api = context |> Map.get("AWS_LAMBDA_RUNTIME_API") "http://#{aws_lambda_runtime_api}/2018-06-01/runtime/invocation/#{request_id}/response" end defp response({:ok, result}) do response("200", result) end defp response({:error, result}) do response("400", result) end defp response(status_code, body) do %{ statusCode: status_code, body: body, headers: %{ "Content-Type": "application/json" } } end end end end