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
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// source: generator/integration_tests/test.proto

#include "generator/integration_tests/golden/internal/golden_kitchen_sink_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/status_or.h"
#include <generator/integration_tests/test.grpc.pb.h>
Expand Down Expand Up @@ -115,6 +116,11 @@ void GoldenKitchenSinkMetadata::SetMetadata(grpc::ClientContext& context,

void GoldenKitchenSinkMetadata::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata(
"x-goog-user-project", options.get<UserProjectOption>());
}
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ auto constexpr kBackoffScaling = 2.0;
Options GoldenKitchenSinkDefaultOptions(Options options) {
if (!options.has<EndpointOption>()) {
auto env = internal::GetEnv("GOLDEN_KITCHEN_SINK_ENDPOINT");
options.set<EndpointOption>(env && !env->empty() ? *env : "goldenkitchensink.googleapis.com");
options.set<EndpointOption>(
env && !env->empty() ? *env : "goldenkitchensink.googleapis.com");
}
if (!options.has<UserProjectOption>()) {
auto env = internal::GetEnv("GOOGLE_CLOUD_CPP_USER_PROJECT");
if (env.has_value() && !env->empty()) options.set<UserProjectOption>(*env);
}
if (auto emulator = internal::GetEnv("GOLDEN_KITCHEN_SINK_EMULATOR_HOST")) {
options.set<EndpointOption>(*emulator).set<GrpcCredentialOption>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// source: generator/integration_tests/test.proto

#include "generator/integration_tests/golden/internal/golden_thing_admin_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/status_or.h"
#include <generator/integration_tests/test.grpc.pb.h>
Expand Down Expand Up @@ -224,6 +225,11 @@ void GoldenThingAdminMetadata::SetMetadata(grpc::ClientContext& context,

void GoldenThingAdminMetadata::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata(
"x-goog-user-project", options.get<UserProjectOption>());
}
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ auto constexpr kBackoffScaling = 2.0;
Options GoldenThingAdminDefaultOptions(Options options) {
if (!options.has<EndpointOption>()) {
auto env = internal::GetEnv("GOLDEN_KITCHEN_SINK_ENDPOINT");
options.set<EndpointOption>(env && !env->empty() ? *env : "test.googleapis.com");
options.set<EndpointOption>(
env && !env->empty() ? *env : "test.googleapis.com");
}
if (!options.has<UserProjectOption>()) {
auto env = internal::GetEnv("GOOGLE_CLOUD_CPP_USER_PROJECT");
if (env.has_value() && !env->empty()) options.set<UserProjectOption>(*env);
}
if (auto emulator = internal::GetEnv("GOLDEN_KITCHEN_SINK_EMULATOR_HOST")) {
options.set<EndpointOption>(*emulator).set<GrpcCredentialOption>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

#include "generator/integration_tests/golden/internal/golden_kitchen_sink_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/testing_util/status_matchers.h"
#include "google/cloud/testing_util/validate_metadata.h"
Expand All @@ -36,7 +37,10 @@ using ::google::test::admin::database::v1::TailLogEntriesRequest;
using ::google::test::admin::database::v1::TailLogEntriesResponse;
using ::google::test::admin::database::v1::WriteObjectRequest;
using ::google::test::admin::database::v1::WriteObjectResponse;
using ::testing::_;
using ::testing::Contains;
using ::testing::Not;
using ::testing::Pair;
using ::testing::Return;

class MetadataDecoratorTest : public ::testing::Test {
Expand All @@ -55,6 +59,47 @@ class MetadataDecoratorTest : public ::testing::Test {
std::string expected_api_client_header_;
};

/// Verify the x-goog-user-project metadata is set.
TEST_F(MetadataDecoratorTest, UserProject) {
// We do this for a single RPC, we are using some knowledge of the
// implementation to assert that this is enough.
EXPECT_CALL(*mock_, GenerateAccessToken)
.WillOnce([](grpc::ClientContext& context,
google::test::admin::database::v1::
GenerateAccessTokenRequest const&) {
auto metadata = testing_util::GetMetadata(context);
EXPECT_THAT(metadata, Not(Contains(Pair("x-goog-user-project", _))));
return TransientError();
})
.WillOnce([](grpc::ClientContext& context,
google::test::admin::database::v1::
GenerateAccessTokenRequest const&) {
auto metadata = testing_util::GetMetadata(context);
EXPECT_THAT(metadata,
Contains(Pair("x-goog-user-project", "test-user-project")));
return TransientError();
});

GoldenKitchenSinkMetadata stub(mock_);
// First try without any UserProjectOption
{
internal::OptionsSpan span(Options{});
grpc::ClientContext context;
google::test::admin::database::v1::GenerateAccessTokenRequest request;
auto status = stub.GenerateAccessToken(context, request);
EXPECT_EQ(TransientError(), status.status());
}
// Then try with a UserProjectOption
{
internal::OptionsSpan span(
Options{}.set<UserProjectOption>("test-user-project"));
grpc::ClientContext context;
google::test::admin::database::v1::GenerateAccessTokenRequest request;
auto status = stub.GenerateAccessToken(context, request);
EXPECT_EQ(TransientError(), status.status());
}
}

TEST_F(MetadataDecoratorTest, GenerateAccessToken) {
EXPECT_CALL(*mock_, GenerateAccessToken)
.WillOnce([this](grpc::ClientContext& context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "generator/integration_tests/golden/internal/golden_kitchen_sink_option_defaults.h"
#include "google/cloud/common_options.h"
#include "google/cloud/grpc_options.h"
#include "google/cloud/internal/setenv.h"
#include "google/cloud/testing_util/scoped_environment.h"
#include <gtest/gtest.h>
#include <memory>

Expand All @@ -25,28 +25,55 @@ namespace golden_internal {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace {

using ::google::cloud::testing_util::ScopedEnvironment;

TEST(GoldenKitchenSinkDefaultOptions, DefaultEndpoint) {
auto env = ScopedEnvironment("GOLDEN_KITCHEN_SINK_ENDPOINT", absl::nullopt);
Options options;
auto updated_options = GoldenKitchenSinkDefaultOptions(options);
EXPECT_EQ("goldenkitchensink.googleapis.com",
updated_options.get<EndpointOption>());
}

TEST(GoldenKitchenSinkDefaultOptions, EnvVarEndpoint) {
internal::SetEnv("GOLDEN_KITCHEN_SINK_ENDPOINT", "foo.googleapis.com");
auto env =
ScopedEnvironment("GOLDEN_KITCHEN_SINK_ENDPOINT", "foo.googleapis.com");
Options options;
auto updated_options = GoldenKitchenSinkDefaultOptions(options);
EXPECT_EQ("foo.googleapis.com", updated_options.get<EndpointOption>());
}

TEST(GoldenKitchenSinkDefaultOptions, OptionEndpoint) {
internal::SetEnv("GOLDEN_KITCHEN_SINK_ENDPOINT", "foo.googleapis.com");
auto env =
ScopedEnvironment("GOLDEN_KITCHEN_SINK_ENDPOINT", "foo.googleapis.com");
Options options;
options.set<EndpointOption>("bar.googleapis.com");
auto updated_options = GoldenKitchenSinkDefaultOptions(options);
EXPECT_EQ("bar.googleapis.com", updated_options.get<EndpointOption>());
}

TEST(GoldenKitchenSinkDefaultOptions, DefaultUserProject) {
auto env = ScopedEnvironment("GOOGLE_CLOUD_CPP_USER_PROJECT", absl::nullopt);
Options options;
auto updated_options = GoldenKitchenSinkDefaultOptions(options);
EXPECT_FALSE(updated_options.has<UserProjectOption>());
EXPECT_EQ("", updated_options.get<UserProjectOption>());
}

TEST(GoldenKitchenSinkDefaultOptions, EnvVarUserProject) {
auto env = ScopedEnvironment("GOOGLE_CLOUD_CPP_USER_PROJECT", "test-project");
Options options;
auto updated_options = GoldenKitchenSinkDefaultOptions(options);
EXPECT_EQ("test-project", updated_options.get<UserProjectOption>());
}

TEST(GoldenKitchenSinkDefaultOptions, OptionUserProject) {
auto env = ScopedEnvironment("GOOGLE_CLOUD_CPP_USER_PROJECT", "test-project");
auto options = Options{}.set<UserProjectOption>("another-project");
auto updated_options = GoldenKitchenSinkDefaultOptions(options);
EXPECT_EQ("another-project", updated_options.get<UserProjectOption>());
}

} // namespace
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace golden_internal
Expand Down
6 changes: 6 additions & 0 deletions generator/internal/metadata_decorator_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ Status MetadataDecoratorGenerator::GenerateCc() {
CcPrint("\n");
CcLocalIncludes({vars("metadata_header_path"),
"google/cloud/internal/api_client_header.h",
"google/cloud/common_options.h",
"google/cloud/status_or.h"});
CcSystemIncludes({vars("proto_grpc_header_path"), "memory"});

Expand Down Expand Up @@ -342,6 +343,11 @@ void $metadata_class_name$::SetMetadata(grpc::ClientContext& context,

void $metadata_class_name$::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata(
"x-goog-user-project", options.get<UserProjectOption>());
}
}
)""");

Expand Down
19 changes: 13 additions & 6 deletions generator/internal/option_defaults_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,19 @@ Status OptionDefaultsGenerator::GenerateCc() {
// clang-format on

CcPrint( // clang-format off
{{"\n"
"Options $service_name$DefaultOptions(Options options) {\n"
" if (!options.has<EndpointOption>()) {\n"
" auto env = internal::GetEnv(\"$service_endpoint_env_var$\");\n"
" options.set<EndpointOption>(env && !env->empty() ? *env : \"$service_endpoint$\");\n"
" }\n"},
{{R"""(
Options $service_name$DefaultOptions(Options options) {
if (!options.has<EndpointOption>()) {
auto env = internal::GetEnv("$service_endpoint_env_var$");
options.set<EndpointOption>(
env && !env->empty() ? *env : "$service_endpoint$");
}
if (!options.has<UserProjectOption>()) {
auto env = internal::GetEnv("GOOGLE_CLOUD_CPP_USER_PROJECT");
if (env.has_value() && !env->empty()) options.set<UserProjectOption>(*env);
Comment on lines +100 to +104
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably use either env or env.has_value() consistently when they're this close together.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack. I will send a PR to clean this up, I think there is some opportunity for refactoring too.

}
Comment on lines +102 to +105
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be adding this to the non-generated default options?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I am planning to do that.

)"""
},
{[this]{return vars("emulator_endpoint_env_var").empty();}, "",
" if (auto emulator = internal::GetEnv(\"$emulator_endpoint_env_var$\")) {\n"
" options.set<EndpointOption>(*emulator).set<GrpcCredentialOption>(\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// source: google/cloud/accessapproval/v1/accessapproval.proto

#include "google/cloud/accessapproval/internal/access_approval_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/status_or.h"
#include <google/cloud/accessapproval/v1/accessapproval.grpc.pb.h>
Expand Down Expand Up @@ -103,6 +104,11 @@ void AccessApprovalMetadata::SetMetadata(grpc::ClientContext& context,

void AccessApprovalMetadata::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata("x-goog-user-project",
options.get<UserProjectOption>());
}
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ Options AccessApprovalDefaultOptions(Options options) {
options.set<EndpointOption>(
env && !env->empty() ? *env : "accessapproval.googleapis.com");
}
if (!options.has<UserProjectOption>()) {
auto env = internal::GetEnv("GOOGLE_CLOUD_CPP_USER_PROJECT");
if (env.has_value() && !env->empty()) options.set<UserProjectOption>(*env);
}
if (!options.has<GrpcCredentialOption>()) {
options.set<GrpcCredentialOption>(grpc::GoogleDefaultCredentials());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// source: google/identity/accesscontextmanager/v1/access_context_manager.proto

#include "google/cloud/accesscontextmanager/internal/access_context_manager_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/status_or.h"
#include <google/identity/accesscontextmanager/v1/access_context_manager.grpc.pb.h>
Expand Down Expand Up @@ -286,6 +287,11 @@ void AccessContextManagerMetadata::SetMetadata(

void AccessContextManagerMetadata::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata("x-goog-user-project",
options.get<UserProjectOption>());
}
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Options AccessContextManagerDefaultOptions(Options options) {
options.set<EndpointOption>(
env && !env->empty() ? *env : "accesscontextmanager.googleapis.com");
}
if (!options.has<UserProjectOption>()) {
auto env = internal::GetEnv("GOOGLE_CLOUD_CPP_USER_PROJECT");
if (env.has_value() && !env->empty()) options.set<UserProjectOption>(*env);
}
if (!options.has<GrpcCredentialOption>()) {
options.set<GrpcCredentialOption>(grpc::GoogleDefaultCredentials());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// source: google/cloud/apigateway/v1/apigateway_service.proto

#include "google/cloud/apigateway/internal/api_gateway_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/status_or.h"
#include <google/cloud/apigateway/v1/apigateway_service.grpc.pb.h>
Expand Down Expand Up @@ -186,6 +187,11 @@ void ApiGatewayServiceMetadata::SetMetadata(grpc::ClientContext& context,

void ApiGatewayServiceMetadata::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata("x-goog-user-project",
options.get<UserProjectOption>());
}
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ Options ApiGatewayServiceDefaultOptions(Options options) {
options.set<EndpointOption>(
env && !env->empty() ? *env : "apigateway.googleapis.com");
}
if (!options.has<UserProjectOption>()) {
auto env = internal::GetEnv("GOOGLE_CLOUD_CPP_USER_PROJECT");
if (env.has_value() && !env->empty()) options.set<UserProjectOption>(*env);
}
if (!options.has<GrpcCredentialOption>()) {
options.set<GrpcCredentialOption>(grpc::GoogleDefaultCredentials());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// source: google/cloud/apigeeconnect/v1/connection.proto

#include "google/cloud/apigeeconnect/internal/connection_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/status_or.h"
#include <google/cloud/apigeeconnect/v1/connection.grpc.pb.h>
Expand Down Expand Up @@ -49,6 +50,11 @@ void ConnectionServiceMetadata::SetMetadata(grpc::ClientContext& context,

void ConnectionServiceMetadata::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata("x-goog-user-project",
options.get<UserProjectOption>());
}
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ Options ConnectionServiceDefaultOptions(Options options) {
options.set<EndpointOption>(
env && !env->empty() ? *env : "apigeeconnect.googleapis.com");
}
if (!options.has<UserProjectOption>()) {
auto env = internal::GetEnv("GOOGLE_CLOUD_CPP_USER_PROJECT");
if (env.has_value() && !env->empty()) options.set<UserProjectOption>(*env);
}
if (!options.has<GrpcCredentialOption>()) {
options.set<GrpcCredentialOption>(grpc::GoogleDefaultCredentials());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// source: google/appengine/v1/appengine.proto

#include "google/cloud/appengine/internal/applications_metadata_decorator.h"
#include "google/cloud/common_options.h"
#include "google/cloud/internal/api_client_header.h"
#include "google/cloud/status_or.h"
#include <google/appengine/v1/appengine.grpc.pb.h>
Expand Down Expand Up @@ -93,6 +94,11 @@ void ApplicationsMetadata::SetMetadata(grpc::ClientContext& context,

void ApplicationsMetadata::SetMetadata(grpc::ClientContext& context) {
context.AddMetadata("x-goog-api-client", api_client_header_);
auto const& options = internal::CurrentOptions();
if (options.has<UserProjectOption>()) {
context.AddMetadata("x-goog-user-project",
options.get<UserProjectOption>());
}
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Loading