Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 0 additions & 48 deletions lib/grpc_reflection/server/process.ex

This file was deleted.

92 changes: 66 additions & 26 deletions lib/grpc_reflection/server/v1.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,54 +13,94 @@ defmodule GrpcReflection.Server.V1 do

response =
state_mod
|> GrpcReflection.Server.Process.reflect(request.message_request)
|> build_response()
|> reflect(request.message_request)
|> handle_errors()

message =
struct(ServerReflectionResponse,
%ServerReflectionResponse{
valid_host: request.host,
original_request: request,
message_response: response
)
}

Server.send_reply(server, message)
end)
end

defp build_response({:ok, {:file_descriptor_response, file_descriptor}}) do
{:file_descriptor_response,
%Grpc.Reflection.V1.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(file_descriptor)]
}}
end

defp build_response({:ok, {:all_extension_numbers_response, body}}) do
encoded =
struct(
Grpc.Reflection.V1.ExtensionNumberResponse,
body
)

{:all_extension_numbers_response, encoded}
end
defp handle_errors({:ok, payload}), do: payload

defp build_response({:ok, {:list_services_response, %{service: services}}}) do
{:list_services_response, %{service: services}}
end

defp build_response({:error, :unimplemented}) do
defp handle_errors({:error, :unimplemented}) do
{:error_response,
%ErrorResponse{
error_code: GRPC.Status.unimplemented(),
error_message: "Operation not supported"
}}
end

defp build_response({:error, reason}) do
defp handle_errors({:error, reason}) do
{:error_response,
%ErrorResponse{
error_code: GRPC.Status.not_found(),
error_message: reason
}}
end

def reflect(state_mod, {:list_services, _}) do
state_mod.list_services()
|> Enum.map(fn name -> %Grpc.Reflection.V1.ServiceResponse{name: name} end)
|> then(fn services ->
{:ok, {:list_services_response, %Grpc.Reflection.V1.ListServiceResponse{service: services}}}
end)
end

def reflect(state_mod, {:file_containing_symbol, symbol}) do
with {:ok, filename} <- state_mod.get_filename_by_symbol(symbol),
{:ok, descriptor} <- state_mod.get_by_filename(filename) do
{:ok,
{:file_descriptor_response,
%Grpc.Reflection.V1.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(descriptor)]
}}}
end
end

def reflect(state_mod, {:file_by_filename, filename}) do
with {:ok, descriptor} <- state_mod.get_by_filename(filename) do
{:ok,
{:file_descriptor_response,
%Grpc.Reflection.V1.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(descriptor)]
}}}
end
end

def reflect(
state_mod,
{:file_containing_extension,
%{containing_type: containing_type, extension_number: _extension_number}}
) do
with {:ok, descriptor} <- state_mod.get_by_extension(containing_type) do
{:ok,
{:file_descriptor_response,
%Grpc.Reflection.V1.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(descriptor)]
}}}
end
end

def reflect(state_mod, {:all_extension_numbers_of_type, mod}) do
with {:ok, extension_numbers} <- state_mod.get_extension_numbers_by_type(mod) do
{:ok,
{:all_extension_numbers_response,
%Grpc.Reflection.V1.ExtensionNumberResponse{
base_type_name: mod,
extension_number: extension_numbers
}}}
end
end

def reflect(_state_mod, message_request) do
Logger.warning("received unexpected reflection request: #{inspect(message_request)}")
{:error, :unimplemented}
end
end
91 changes: 67 additions & 24 deletions lib/grpc_reflection/server/v1alpha.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,52 +13,95 @@ defmodule GrpcReflection.Server.V1alpha do

response =
state_mod
|> GrpcReflection.Server.Process.reflect(request.message_request)
|> build_response()
|> reflect(request.message_request)
|> handle_errors()

message =
struct(ServerReflectionResponse,
%ServerReflectionResponse{
valid_host: request.host,
original_request: request,
message_response: response
)
}

Server.send_reply(server, message)
end)
end

defp build_response({:ok, {:file_descriptor_response, file_descriptor}}) do
{:file_descriptor_response,
%Grpc.Reflection.V1alpha.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(file_descriptor)]
}}
end

defp build_response({:ok, {:all_extension_numbers_response, body}}) do
{:all_extension_numbers_response,
struct(
Grpc.Reflection.V1alpha.ExtensionNumberResponse,
body
)}
end

defp build_response({:ok, {:list_services_response, %{service: services}}}) do
{:list_services_response, %{service: services}}
end
defp handle_errors({:ok, payload}), do: payload

defp build_response({:error, :unimplemented}) do
defp handle_errors({:error, :unimplemented}) do
{:error_response,
%ErrorResponse{
error_code: GRPC.Status.unimplemented(),
error_message: "Operation not supported"
}}
end

defp build_response({:error, reason}) do
defp handle_errors({:error, reason}) do
{:error_response,
%ErrorResponse{
error_code: GRPC.Status.not_found(),
error_message: reason
}}
end

def reflect(state_mod, {:list_services, _}) do
state_mod.list_services()
|> Enum.map(fn name -> %Grpc.Reflection.V1alpha.ServiceResponse{name: name} end)
|> then(fn services ->
{:ok,
{:list_services_response, %Grpc.Reflection.V1alpha.ListServiceResponse{service: services}}}
end)
end

def reflect(state_mod, {:file_containing_symbol, symbol}) do
with {:ok, filename} <- state_mod.get_filename_by_symbol(symbol),
{:ok, descriptor} <- state_mod.get_by_filename(filename) do
{:ok,
{:file_descriptor_response,
%Grpc.Reflection.V1alpha.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(descriptor)]
}}}
end
end

def reflect(state_mod, {:file_by_filename, filename}) do
with {:ok, descriptor} <- state_mod.get_by_filename(filename) do
{:ok,
{:file_descriptor_response,
%Grpc.Reflection.V1alpha.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(descriptor)]
}}}
end
end

def reflect(
state_mod,
{:file_containing_extension,
%{containing_type: containing_type, extension_number: _extension_number}}
) do
with {:ok, descriptor} <- state_mod.get_by_extension(containing_type) do
{:ok,
{:file_descriptor_response,
%Grpc.Reflection.V1alpha.FileDescriptorResponse{
file_descriptor_proto: [Google.Protobuf.FileDescriptorProto.encode(descriptor)]
}}}
end
end

def reflect(state_mod, {:all_extension_numbers_of_type, mod}) do
with {:ok, extension_numbers} <- state_mod.get_extension_numbers_by_type(mod) do
{:ok,
{:all_extension_numbers_response,
%Grpc.Reflection.V1alpha.ExtensionNumberResponse{
base_type_name: mod,
extension_number: extension_numbers
}}}
end
end

def reflect(_state_mod, message_request) do
Logger.warning("received unexpected reflection request: #{inspect(message_request)}")
{:error, :unimplemented}
end
end
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"makeup_erlang": {:hex, :makeup_erlang, "1.0.3", "4252d5d4098da7415c390e847c814bad3764c94a814a0b4245176215615e1035", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "953297c02582a33411ac6208f2c6e55f0e870df7f80da724ed613f10e6706afd"},
"mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"},
"nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"},
"protobuf": {:hex, :protobuf, "0.15.0", "c9fc1e9fc1682b05c601df536d5ff21877b55e2023e0466a3855cc1273b74dcb", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "5d7bb325319db1d668838d2691c31c7b793c34111aec87d5ee467a39dac6e051"},
"protobuf": {:hex, :protobuf, "0.16.0", "d1878725105d49162977cf3408ccc3eac4f3532e26e5a9e250f2c624175d10f6", [:mix], [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "f0d0d3edd8768130f24cc2cfc41320637d32c80110e80d13f160fa699102c828"},
"ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
}