Current section
Files
Jump to
Current section
Files
lib/grpc_reflection/server/v1.ex
defmodule GrpcReflection.Server.V1 do
@moduledoc false
alias Grpc.Reflection.V1.ErrorResponse
alias Grpc.Reflection.V1.ServerReflectionResponse
alias GRPC.Server
require Logger
def server_reflection_info(state_mod, request_stream, server) do
Enum.map(request_stream, fn request ->
Logger.info("Received v1 reflection request: " <> inspect(request.message_request))
state_mod
|> reflection_request(request.message_request)
|> case do
{:ok, message_response} ->
%ServerReflectionResponse{
valid_host: request.host,
original_request: request,
message_response: message_response
}
{:error, reason} ->
%ServerReflectionResponse{
valid_host: request.host,
original_request: request,
message_response:
{:error_response,
%ErrorResponse{
error_code: GRPC.Status.not_found(),
error_message: reason
}}
}
{:unexpected, message} ->
Logger.warning(message)
%ServerReflectionResponse{
valid_host: request.host,
original_request: request,
message_response:
{:error_response,
%ErrorResponse{
error_code: GRPC.Status.unimplemented(),
error_message: "Operation not supported"
}}
}
end
|> then(&Server.send_reply(server, &1))
end)
end
def reflection_request(state_mod, message_request) do
case message_request do
{:list_services, _} ->
state_mod.list_services()
|> Enum.map(fn name -> %{name: name} end)
|> then(fn services ->
{:ok, {:list_services_response, %{service: services}}}
end)
{:file_containing_symbol, symbol} ->
with {:ok, description} <- state_mod.get_by_symbol(symbol) do
{:ok,
{:file_descriptor_response,
struct(Grpc.Reflection.V1.FileDescriptorResponse, description)}}
end
{:file_by_filename, filename} ->
with {:ok, description} <- state_mod.get_by_filename(filename) do
{:ok,
{:file_descriptor_response,
struct(Grpc.Reflection.V1.FileDescriptorResponse, description)}}
end
{:file_containing_extension,
%Grpc.Reflection.V1.ExtensionRequest{
containing_type: containing_type,
extension_number: _extension_number
}} ->
with {:ok, description} <- state_mod.get_by_extension(containing_type) do
{:ok,
{:file_descriptor_response,
struct(Grpc.Reflection.V1.FileDescriptorResponse, description)}}
end
{:all_extension_numbers_of_type, mod} ->
with {:ok, extension_numbers} <- state_mod.get_extension_numbers_by_type(mod) do
{:ok,
{:all_extension_numbers_response,
struct(
Grpc.Reflection.V1.ExtensionNumberResponse,
%{base_type_name: mod, extension_number: extension_numbers}
)}}
end
other ->
{:unexpected, "received inexpected reflection request: #{inspect(other)}"}
end
end
end