#include <proxy_service.hpp>
#include <grpcpp/client_context.h>
#include <grpcpp/server_context.h>
#include <grpcpp/support/byte_buffer.h>
namespace samples {
namespace {
std::string_view ToStringView(grpc::string_ref str) { return {str.data(), str.size()}; }
grpc::string ToGrpcString(grpc::string_ref str) { return {str.data(), str.size()}; }
for (const auto& [key, value] : server_context.client_metadata()) {
call_options.
AddMetadata(ToStringView(key), ToStringView(value));
}
call_options.
AddMetadata(
"proxy-name",
"grpc-generic-proxy");
}
void ProxyTrailingResponseMetadata(const grpc::ClientContext& client_context, grpc::ServerContext& server_context) {
for (const auto& [key, value] : client_context.GetServerTrailingMetadata()) {
server_context.AddTrailingMetadata(ToGrpcString(key), ToGrpcString(value));
}
server_context.AddTrailingMetadata("proxy-name", "grpc-generic-proxy");
}
}
client_(context
.GetClient()) {}
ProxyService::GenericResult ProxyService::Handle(GenericCallContext& context, GenericReaderWriter& stream) {
context.SetMetricsCallName(context.GetCallName());
grpc::ByteBuffer request_bytes;
if (!stream.Read(request_bytes)) {
return grpc::Status{grpc::StatusCode::INVALID_ARGUMENT, "Expected exactly 1 request, given: 0"};
}
grpc::ByteBuffer ignored_request_bytes;
if (stream.Read(ignored_request_bytes)) {
return grpc::Status{grpc::StatusCode::INVALID_ARGUMENT, "Expected exactly 1 request, given: at least 2"};
}
ProxyRequestMetadata(context.GetServerContext(), call_options);
auto future = client_.AsyncUnaryCall(context.GetCallName(), request_bytes, std::move(call_options));
grpc::ByteBuffer response_bytes;
try {
response_bytes = future.Get();
ProxyTrailingResponseMetadata(future.GetContext().GetClientContext(), context.GetServerContext());
return grpc::Status{grpc::StatusCode::UNAVAILABLE, "Failed to proxy the request"};
}
ProxyTrailingResponseMetadata(future.GetContext().GetClientContext(), context.GetServerContext());
return response_bytes;
}
}