Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion source/common/grpc/google_async_client_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ GoogleAsyncClientImpl::GoogleAsyncClientImpl(Event::Dispatcher& dispatcher,
// smart enough to do connection pooling and reuse with identical channel args, so this should
// have comparable overhead to what we are doing in Grpc::AsyncClientImpl, i.e. no expensive
// new connection implied.
std::shared_ptr<grpc::Channel> channel = GoogleGrpcUtils::createChannel(config, api);
std::shared_ptr<grpc::Channel> channel = GoogleGrpcUtils::createChannel(config, api, false);
stub_ = stub_factory.createStub(channel);
// Initialize client stats.
// TODO(jmarantz): Capture these names in async_client_manager_impl.cc and
Expand Down
57 changes: 55 additions & 2 deletions source/common/grpc/google_grpc_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,46 @@ getGoogleGrpcChannelCredentials(const envoy::config::core::v3::GrpcService& grpc
return credentials_factory->getChannelCredentials(grpc_service, api);
}

// InitialMetadataInterceptor is used to inject the given initial metadata to gRPC channel.
class InitialMetadataInterceptor : public grpc::experimental::Interceptor {
public:
InitialMetadataInterceptor(
const Protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>& initial_metadata)
: initial_metadata_(initial_metadata) {}

void Intercept(grpc::experimental::InterceptorBatchMethods* methods) override {
if (methods->QueryInterceptionHookPoint(
grpc::experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
auto* metadata_map = methods->GetSendInitialMetadata();
if (metadata_map != nullptr) {
for (const auto& header_value : initial_metadata_) {
metadata_map->insert(std::make_pair(header_value.key(), header_value.value()));
}
}
}
methods->Proceed();
}

private:
const Protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>& initial_metadata_;
};

class InitialMetadataInterceptorFactory
: public grpc::experimental::ClientInterceptorFactoryInterface {
public:
InitialMetadataInterceptorFactory(
const Protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue>& initial_metadata)
: initial_metadata_(initial_metadata) {}

grpc::experimental::Interceptor*
CreateClientInterceptor(grpc::experimental::ClientRpcInfo*) override {
return new InitialMetadataInterceptor(initial_metadata_);
}

private:
const Protobuf::RepeatedPtrField<envoy::config::core::v3::HeaderValue> initial_metadata_;
};

} // namespace

struct BufferInstanceContainer {
Expand Down Expand Up @@ -134,10 +174,23 @@ GoogleGrpcUtils::channelArgsFromConfig(const envoy::config::core::v3::GrpcServic
}

std::shared_ptr<grpc::Channel>
GoogleGrpcUtils::createChannel(const envoy::config::core::v3::GrpcService& config, Api::Api& api) {
GoogleGrpcUtils::createChannel(const envoy::config::core::v3::GrpcService& config, Api::Api& api,
bool enable_initial_metadata_interceptor) {
std::shared_ptr<grpc::ChannelCredentials> creds = getGoogleGrpcChannelCredentials(config, api);
const grpc::ChannelArguments args = channelArgsFromConfig(config);
return CreateCustomChannel(config.google_grpc().target_uri(), creds, args);
if (!enable_initial_metadata_interceptor || config.initial_metadata().empty()) {
// Skip adding initial metadata interceptor if it is not enabled, or initial metadata is not
// configured.
return CreateCustomChannel(config.google_grpc().target_uri(), creds, args);
}

// Create gRPC channel with initial metadata interceptor.
std::vector<std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>>
interceptor_factories;
interceptor_factories.push_back(
std::make_unique<InitialMetadataInterceptorFactory>((config.initial_metadata())));
return ::grpc::experimental::CreateCustomChannelWithInterceptors(
config.google_grpc().target_uri(), creds, args, std::move(interceptor_factories));
}

} // namespace Grpc
Expand Down
5 changes: 4 additions & 1 deletion source/common/grpc/google_grpc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ class GoogleGrpcUtils {
* Build gRPC channel based on the given GrpcService configuration.
* @param config Google gRPC config.
* @param api reference to the Api object
* @param enable_initial_metadata_interceptor enables initial metadata interceptor if it is
* configured.
* @return static std::shared_ptr<grpc::Channel> a gRPC channel.
*/
static std::shared_ptr<grpc::Channel>
createChannel(const envoy::config::core::v3::GrpcService& config, Api::Api& api);
createChannel(const envoy::config::core::v3::GrpcService& config, Api::Api& api,
bool enable_initial_metadata_interceptor);
};

} // namespace Grpc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ Driver::Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config,
// address will be used.
stackdriver_service.mutable_google_grpc()->set_target_uri(GoogleStackdriverTraceAddress);
}
auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(stackdriver_service, api);
auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(stackdriver_service, api, true);
opts.trace_service_stub = ::google::devtools::cloudtrace::v2::TraceService::NewStub(channel);
#else
throw EnvoyException("Opencensus tracer: cannot handle stackdriver google grpc service, "
Expand All @@ -303,7 +303,7 @@ Driver::Driver(const envoy::config::trace::v3::OpenCensusConfig& oc_config,
#ifdef ENVOY_GOOGLE_GRPC
const envoy::config::core::v3::GrpcService& ocagent_service =
oc_config.ocagent_grpc_service();
auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(ocagent_service, api);
auto channel = Envoy::Grpc::GoogleGrpcUtils::createChannel(ocagent_service, api, true);
opts.trace_service_stub =
::opencensus::proto::agent::trace::v1::TraceService::NewStub(channel);
#else
Expand Down