Skip to content
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ TEST(ThingAdminRestMetadataDecoratorTest, DropDatabaseExplicitRoutingMatch) {
EXPECT_THAT(context.GetHeader("x-goog-quota-user"), IsEmpty());
EXPECT_THAT(context.GetHeader("x-server-timeout"), IsEmpty());
EXPECT_THAT(
context.GetHeader("x-goog-request-params")[0],
context.GetHeader("x-goog-request-params").values().front(),
AllOf(
HasSubstr(std::string("project=projects%2Fmy_project")),
HasSubstr(std::string("instance=instances%2Fmy_instance")),
Expand Down
1 change: 1 addition & 0 deletions google/cloud/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ cc_library(
visibility = ["//:__subpackages__"],
deps = [
":google_cloud_cpp_common",
"@abseil-cpp//absl/container:flat_hash_map",
"@abseil-cpp//absl/functional:function_ref",
"@abseil-cpp//absl/types:span",
"@curl",
Expand Down
9 changes: 5 additions & 4 deletions google/cloud/bigquery/v2/minimal/internal/log_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ Result LogWrapper(Functor&& functor, rest_internal::RestContext& context,
TracingOptions const& options) {
auto formatter = [options](std::string* out, auto const& header) {
auto const* delim = options.single_line_mode() ? "&" : "\n";
absl::StrAppend(
out, " { name: \"", header.first, "\" value: \"",
internal::DebugString(absl::StrJoin(header.second, delim), options),
"\" }");
absl::StrAppend(out, " { name: \"", std::string_view{header.first},
"\" value: \"",
internal::DebugString(
absl::StrJoin(header.second.values(), delim), options),
"\" }");
};
GCP_LOG(DEBUG) << where << "() << "
<< request.DebugString(request_name, options) << ", Context {"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ StatusOr<rest_internal::RestRequest> PrepareRestRequest(
if (!rest_context.headers().empty()) {
for (auto const& h : rest_context.headers()) {
if (!h.second.empty()) {
rest_request->AddHeader(h.first, absl::StrJoin(h.second, "&"));
rest_request->AddHeader(h.first, absl::StrJoin(h.second.values(), "&"));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ static auto const kUserProject = "test-only-project";
static auto const kQuotaUser = "test-quota-user";

void VerifyMetadataContext(rest_internal::RestContext& context) {
EXPECT_THAT(context.GetHeader("x-goog-api-client"),
EXPECT_THAT(context.GetHeader("x-goog-api-client").values(),
ElementsAre(internal::HandCraftedLibClientHeader()));
EXPECT_THAT(context.GetHeader("x-goog-request-params"), IsEmpty());
EXPECT_THAT(context.GetHeader("x-goog-user-project"),
EXPECT_THAT(context.GetHeader("x-goog-request-params").values(), IsEmpty());
EXPECT_THAT(context.GetHeader("x-goog-user-project").values(),
ElementsAre(kUserProject));
EXPECT_THAT(context.GetHeader("x-goog-quota-user"), ElementsAre(kQuotaUser));
EXPECT_THAT(context.GetHeader("x-server-timeout"), ElementsAre("3.141"));
EXPECT_THAT(context.GetHeader("x-goog-quota-user").values(),
ElementsAre(kQuotaUser));
EXPECT_THAT(context.GetHeader("x-server-timeout").values(),
ElementsAre("3.141"));
}

Options GetMetadataOptions() {
Expand Down
6 changes: 6 additions & 0 deletions google/cloud/google_cloud_cpp_rest_internal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"""Automatically generated source lists for google_cloud_cpp_rest_internal - DO NOT EDIT."""

google_cloud_cpp_rest_internal_hdrs = [
"internal/async_rest_retry_loop.h",
"internal/binary_data_as_debug_string.h",
"internal/curl_handle.h",
"internal/curl_handle_factory.h",
Expand Down Expand Up @@ -54,6 +55,7 @@ google_cloud_cpp_rest_internal_hdrs = [
"internal/oauth2_logging_credentials.h",
"internal/oauth2_minimal_iam_credentials_rest.h",
"internal/oauth2_refreshing_credentials_wrapper.h",
"internal/oauth2_regional_access_boundary_token_manager.h",
"internal/oauth2_service_account_credentials.h",
"internal/oauth2_universe_domain.h",
"internal/parse_service_account_p12_file.h",
Expand All @@ -65,6 +67,8 @@ google_cloud_cpp_rest_internal_hdrs = [
"internal/rest_opentelemetry.h",
"internal/rest_options.h",
"internal/rest_parse_json_error.h",
"internal/rest_pure_background_threads_impl.h",
"internal/rest_pure_completion_queue_impl.h",
"internal/rest_request.h",
"internal/rest_response.h",
"internal/rest_retry_loop.h",
Expand Down Expand Up @@ -111,6 +115,7 @@ google_cloud_cpp_rest_internal_srcs = [
"internal/oauth2_logging_credentials.cc",
"internal/oauth2_minimal_iam_credentials_rest.cc",
"internal/oauth2_refreshing_credentials_wrapper.cc",
"internal/oauth2_regional_access_boundary_token_manager.cc",
"internal/oauth2_service_account_credentials.cc",
"internal/oauth2_universe_domain.cc",
"internal/openssl/parse_service_account_p12_file.cc",
Expand All @@ -121,6 +126,7 @@ google_cloud_cpp_rest_internal_srcs = [
"internal/rest_lro_helpers.cc",
"internal/rest_opentelemetry.cc",
"internal/rest_parse_json_error.cc",
"internal/rest_pure_completion_queue_impl.cc",
"internal/rest_request.cc",
"internal/rest_response.cc",
"internal/rest_set_metadata.cc",
Expand Down
10 changes: 9 additions & 1 deletion google/cloud/google_cloud_cpp_rest_internal.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ endif ()
# the library
add_library(
google_cloud_cpp_rest_internal # cmake-format: sort
internal/async_rest_retry_loop.h
internal/binary_data_as_debug_string.cc
internal/binary_data_as_debug_string.h
internal/curl_handle.cc
Expand Down Expand Up @@ -92,6 +93,8 @@ add_library(
internal/oauth2_minimal_iam_credentials_rest.h
internal/oauth2_refreshing_credentials_wrapper.cc
internal/oauth2_refreshing_credentials_wrapper.h
internal/oauth2_regional_access_boundary_token_manager.cc
internal/oauth2_regional_access_boundary_token_manager.h
internal/oauth2_service_account_credentials.cc
internal/oauth2_service_account_credentials.h
internal/oauth2_universe_domain.cc
Expand All @@ -113,6 +116,9 @@ add_library(
internal/rest_options.h
internal/rest_parse_json_error.cc
internal/rest_parse_json_error.h
internal/rest_pure_background_threads_impl.h
internal/rest_pure_completion_queue_impl.cc
internal/rest_pure_completion_queue_impl.h
internal/rest_request.cc
internal/rest_request.h
internal/rest_response.cc
Expand All @@ -137,7 +143,7 @@ add_library(
target_link_libraries(
google_cloud_cpp_rest_internal
PUBLIC absl::span google-cloud-cpp::common CURL::libcurl
nlohmann_json::nlohmann_json)
absl::flat_hash_map nlohmann_json::nlohmann_json)
if (WIN32)
target_compile_definitions(google_cloud_cpp_rest_internal
PRIVATE WIN32_LEAN_AND_MEAN)
Expand Down Expand Up @@ -197,6 +203,7 @@ google_cloud_cpp_add_pkgconfig(
"Provides REST Transport for the Google Cloud C++ Client Library."
"google_cloud_cpp_common"
"libcurl"
"absl_flat_hash_map"
NON_WIN32_REQUIRES
openssl
WIN32_LIBS
Expand Down Expand Up @@ -279,6 +286,7 @@ if (BUILD_TESTING)
internal/oauth2_logging_credentials_test.cc
internal/oauth2_minimal_iam_credentials_rest_test.cc
internal/oauth2_refreshing_credentials_wrapper_test.cc
internal/oauth2_regional_access_boundary_token_manager_test.cc
internal/oauth2_service_account_credentials_test.cc
internal/oauth2_universe_domain_test.cc
internal/populate_rest_options_test.cc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ google_cloud_cpp_rest_internal_unit_tests = [
"internal/oauth2_logging_credentials_test.cc",
"internal/oauth2_minimal_iam_credentials_rest_test.cc",
"internal/oauth2_refreshing_credentials_wrapper_test.cc",
"internal/oauth2_regional_access_boundary_token_manager_test.cc",
"internal/oauth2_service_account_credentials_test.cc",
"internal/oauth2_universe_domain_test.cc",
"internal/populate_rest_options_test.cc",
Expand Down
1 change: 0 additions & 1 deletion google/cloud/google_cloud_cpp_rest_protobuf_internal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ google_cloud_cpp_rest_protobuf_internal_hdrs = [
"internal/async_rest_polling_loop.h",
"internal/async_rest_polling_loop_custom.h",
"internal/async_rest_polling_loop_impl.h",
"internal/async_rest_retry_loop.h",
"internal/rest_background_threads_impl.h",
"internal/rest_completion_queue_impl.h",
"internal/rest_stub_helpers.h",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ add_library(
internal/async_rest_polling_loop.h
internal/async_rest_polling_loop_custom.h
internal/async_rest_polling_loop_impl.h
internal/async_rest_retry_loop.h
internal/rest_background_threads_impl.cc
internal/rest_background_threads_impl.h
internal/rest_completion_queue_impl.cc
Expand Down
35 changes: 19 additions & 16 deletions google/cloud/internal/async_rest_retry_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_INTERNAL_ASYNC_REST_RETRY_LOOP_H

#include "google/cloud/backoff_policy.h"
#include "google/cloud/completion_queue.h"
// #include "google/cloud/completion_queue.h"
#include "google/cloud/future.h"
#include "google/cloud/idempotency.h"
#include "google/cloud/internal/call_context.h"
#include "google/cloud/internal/grpc_opentelemetry.h"
#include "google/cloud/internal/invoke_result.h"
#include "google/cloud/internal/opentelemetry.h"
#include "google/cloud/internal/rest_context.h"
#include "google/cloud/internal/retry_loop_helpers.h"
#include "google/cloud/options.h"
Expand Down Expand Up @@ -167,14 +167,15 @@ struct FutureValueType<future<T>> {
* functions. If the value is visible, the retry loop will stop on the next
* callback and/or before the next request or timer is issued.
*/
template <typename Functor, typename Request, typename RetryPolicyType>
template <typename Functor, typename Request, typename RetryPolicyType,
typename CompletionQueueType>
class AsyncRestRetryLoopImpl
: public std::enable_shared_from_this<
AsyncRestRetryLoopImpl<Functor, Request, RetryPolicyType>> {
: public std::enable_shared_from_this<AsyncRestRetryLoopImpl<
Functor, Request, RetryPolicyType, CompletionQueueType>> {
public:
AsyncRestRetryLoopImpl(std::unique_ptr<RetryPolicyType> retry_policy,
std::unique_ptr<BackoffPolicy> backoff_policy,
Idempotency idempotency, CompletionQueue cq,
Idempotency idempotency, CompletionQueueType cq,
Functor&& functor, internal::ImmutableOptions options,
Request request, char const* location)
: retry_policy_(std::move(retry_policy)),
Expand All @@ -194,7 +195,7 @@ class AsyncRestRetryLoopImpl
~AsyncRestRetryLoopImpl() = default;

using ReturnType = ::google::cloud::internal::invoke_result_t<
Functor, CompletionQueue&, std::unique_ptr<RestContext>,
Functor, CompletionQueueType&, std::unique_ptr<RestContext>,
internal::ImmutableOptions, Request const&>;
using T = typename FutureValueType<ReturnType>::value_type;

Expand Down Expand Up @@ -329,7 +330,7 @@ class AsyncRestRetryLoopImpl
std::unique_ptr<RetryPolicyType> retry_policy_;
std::unique_ptr<BackoffPolicy> backoff_policy_;
Idempotency idempotency_ = Idempotency::kNonIdempotent;
CompletionQueue cq_;
CompletionQueueType cq_;
std::decay_t<Functor> functor_;
Request request_;
char const* location_ = "unknown";
Expand All @@ -352,24 +353,26 @@ class AsyncRestRetryLoopImpl
*/
template <
typename Functor, typename Request, typename RetryPolicyType,
typename CompletionQueueType,
std::enable_if_t<
google::cloud::internal::is_invocable<
Functor, CompletionQueue&, std::unique_ptr<RestContext>,
Functor, CompletionQueueType&, std::unique_ptr<RestContext>,
google::cloud::internal::ImmutableOptions, Request const&>::value,
int> = 0>
auto AsyncRestRetryLoop(std::unique_ptr<RetryPolicyType> retry_policy,
std::unique_ptr<BackoffPolicy> backoff_policy,
Idempotency idempotency, CompletionQueue cq,
Idempotency idempotency, CompletionQueueType cq,
Functor&& functor, internal::ImmutableOptions options,
Request request, char const* location)
-> google::cloud::internal::invoke_result_t<
Functor, CompletionQueue&, std::unique_ptr<RestContext>,
Functor, CompletionQueueType&, std::unique_ptr<RestContext>,
google::cloud::internal::ImmutableOptions, Request const&> {
auto loop = std::make_shared<
AsyncRestRetryLoopImpl<Functor, Request, RetryPolicyType>>(
std::move(retry_policy), std::move(backoff_policy), idempotency,
std::move(cq), std::forward<Functor>(functor), std::move(options),
std::move(request), location);
auto loop =
std::make_shared<AsyncRestRetryLoopImpl<Functor, Request, RetryPolicyType,
CompletionQueueType>>(
std::move(retry_policy), std::move(backoff_policy), idempotency,
std::move(cq), std::forward<Functor>(functor), std::move(options),
std::move(request), location);
return loop->Start();
}

Expand Down
5 changes: 2 additions & 3 deletions google/cloud/internal/curl_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,9 @@ void CurlImpl::MergeAndWriteHeaders(
}
}

void CurlImpl::SetHeaders(
std::unordered_map<std::string, std::vector<std::string>> const& headers) {
void CurlImpl::SetHeaders(HttpHeaders const& headers) {
for (auto const& header : headers) {
SetHeader(HttpHeader(header.first, header.second));
SetHeader(header.second);
}
}

Expand Down
4 changes: 1 addition & 3 deletions google/cloud/internal/curl_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

namespace google {
Expand Down Expand Up @@ -84,8 +83,7 @@ class CurlImpl {
CurlImpl& operator=(CurlImpl&&) = default;

void SetHeader(HttpHeader header);
void SetHeaders(
std::unordered_map<std::string, std::vector<std::string>> const& headers);
void SetHeaders(HttpHeaders const& headers);

std::string MakeEscapedString(std::string const& s);

Expand Down
10 changes: 6 additions & 4 deletions google/cloud/internal/curl_rest_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@ StatusOr<std::unique_ptr<CurlImpl>> CurlRestClient::CreateCurlImpl(
auto impl =
std::make_unique<CurlImpl>(std::move(handle), handle_factory_, options);
if (credentials_) {
auto auth_header =
credentials_->AuthenticationHeader(std::chrono::system_clock::now());
if (!auth_header.ok()) return std::move(auth_header).status();
impl->SetHeader(HttpHeader(auth_header->first, auth_header->second));
auto auth_headers = credentials_->AuthenticationHeaders(
std::chrono::system_clock::now(), endpoint_address_);
if (!auth_headers.ok()) return std::move(auth_headers).status();
for (auto& header : *auth_headers) {
impl->SetHeader(std::move(header));
}
}
impl->SetHeader(HostHeader(options, endpoint_address_));
impl->SetHeaders(context.headers());
Expand Down
18 changes: 9 additions & 9 deletions google/cloud/internal/curl_rest_client_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ TEST(CurlRestClientStandaloneFunctions, HostHeader) {
std::string expected;
} cases[] = {
{"https://storage.googleapis.com", "storage.googleapis.com",
"Host: storage.googleapis.com"},
{"https://storage.googleapis.com", "", "Host: storage.googleapis.com"},
{"https://storage.googleapis.com", "auth", "Host: auth"},
"host: storage.googleapis.com"},
{"https://storage.googleapis.com", "", "host: storage.googleapis.com"},
{"https://storage.googleapis.com", "auth", "host: auth"},
{"https://storage.googleapis.com:443", "storage.googleapis.com",
"Host: storage.googleapis.com"},
"host: storage.googleapis.com"},
{"https://restricted.googleapis.com", "storage.googleapis.com",
"Host: storage.googleapis.com"},
"host: storage.googleapis.com"},
{"https://private.googleapis.com", "storage.googleapis.com",
"Host: storage.googleapis.com"},
"host: storage.googleapis.com"},
{"https://restricted.googleapis.com", "iamcredentials.googleapis.com",
"Host: iamcredentials.googleapis.com"},
"host: iamcredentials.googleapis.com"},
{"https://private.googleapis.com", "iamcredentials.googleapis.com",
"Host: iamcredentials.googleapis.com"},
"host: iamcredentials.googleapis.com"},
{"http://localhost:8080", "", ""},
{"http://localhost:8080", "auth", "Host: auth"},
{"http://localhost:8080", "auth", "host: auth"},
{"http://[::1]", "", ""},
{"http://[::1]/", "", ""},
{"http://[::1]/foo/bar", "", ""},
Expand Down
34 changes: 17 additions & 17 deletions google/cloud/internal/grpc_opentelemetry.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,23 @@ future<StatusOr<T>> EndSpan(
});
}

/**
* Returns a traced timer, if OpenTelemetry tracing is enabled.
*/
template <typename Rep, typename Period>
future<StatusOr<std::chrono::system_clock::time_point>> TracedAsyncBackoff(
CompletionQueue& cq, Options const& options,
std::chrono::duration<Rep, Period> duration, std::string const& name) {
if (TracingEnabled(options)) {
auto span = MakeSpan(name);
OTelScope scope(span);
auto timer = cq.MakeRelativeTimer(duration);
return EndSpan(std::move(span), std::move(timer));
}
(void)options;
(void)name;
return cq.MakeRelativeTimer(duration);
}
// /**
// * Returns a traced timer, if OpenTelemetry tracing is enabled.
// */
// template <typename Rep, typename Period>
// future<StatusOr<std::chrono::system_clock::time_point>> TracedAsyncBackoff(
// CompletionQueue& cq, Options const& options,
// std::chrono::duration<Rep, Period> duration, std::string const& name) {
// if (TracingEnabled(options)) {
// auto span = MakeSpan(name);
// OTelScope scope(span);
// auto timer = cq.MakeRelativeTimer(duration);
// return EndSpan(std::move(span), std::move(timer));
// }
// (void)options;
// (void)name;
// return cq.MakeRelativeTimer(duration);
// }

} // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
Expand Down
Loading
Loading