diff --git a/BUILD b/BUILD index b49983d16a5..2f9d5a44661 100644 --- a/BUILD +++ b/BUILD @@ -1687,6 +1687,9 @@ grpc_cc_library( hdrs = [ "src/core/lib/gprpp/time.h", ], + external_deps = [ + "absl/strings:str_format", + ], deps = [ "gpr", "gpr_codegen", diff --git a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc index 5c3e0ef1c34..738f22cf031 100644 --- a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc @@ -497,18 +497,15 @@ grpc_error_handle XdsResolver::XdsConfigSelector::CreateMethodConfig( if (route_action.retry_policy.has_value() && !route_action.retry_policy->retry_on.Empty()) { std::vector retry_parts; - const auto base_interval = - route_action.retry_policy->retry_back_off.base_interval.as_timespec(); - const auto max_interval = - route_action.retry_policy->retry_back_off.max_interval.as_timespec(); retry_parts.push_back(absl::StrFormat( "\"retryPolicy\": {\n" " \"maxAttempts\": %d,\n" - " \"initialBackoff\": \"%d.%09ds\",\n" - " \"maxBackoff\": \"%d.%09ds\",\n" + " \"initialBackoff\": \"%s\",\n" + " \"maxBackoff\": \"%s\",\n" " \"backoffMultiplier\": 2,\n", - route_action.retry_policy->num_retries + 1, base_interval.tv_sec, - base_interval.tv_nsec, max_interval.tv_sec, max_interval.tv_nsec)); + route_action.retry_policy->num_retries + 1, + route_action.retry_policy->retry_back_off.base_interval.ToJsonString(), + route_action.retry_policy->retry_back_off.max_interval.ToJsonString())); std::vector code_parts; if (route_action.retry_policy->retry_on.Contains(GRPC_STATUS_CANCELLED)) { code_parts.push_back(" \"CANCELLED\""); @@ -536,9 +533,9 @@ grpc_error_handle XdsResolver::XdsConfigSelector::CreateMethodConfig( // Set timeout. if (route_action.max_stream_duration.has_value() && (route_action.max_stream_duration != Duration::Zero())) { - gpr_timespec ts = route_action.max_stream_duration->as_timespec(); - fields.emplace_back(absl::StrFormat(" \"timeout\": \"%d.%09ds\"", - ts.tv_sec, ts.tv_nsec)); + fields.emplace_back( + absl::StrFormat(" \"timeout\": \"%s\"", + route_action.max_stream_duration->ToJsonString())); } // Handle xDS HTTP filters. XdsRouting::GeneratePerHttpFilterConfigsResult result = diff --git a/src/core/ext/xds/xds_http_fault_filter.cc b/src/core/ext/xds/xds_http_fault_filter.cc index 015556faaec..c257c0a7fc1 100644 --- a/src/core/ext/xds/xds_http_fault_filter.cc +++ b/src/core/ext/xds/xds_http_fault_filter.cc @@ -36,6 +36,7 @@ #include #include "src/core/ext/filters/fault_injection/fault_injection_filter.h" +#include "src/core/ext/xds/xds_common_types.h" #include "src/core/ext/xds/xds_http_filters.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -140,9 +141,8 @@ absl::StatusOr ParseHttpFaultIntoJson( envoy_extensions_filters_common_fault_v3_FaultDelay_fixed_delay( fault_delay); if (delay_duration != nullptr) { - fault_injection_policy_json["delay"] = absl::StrFormat( - "%d.%09ds", google_protobuf_Duration_seconds(delay_duration), - google_protobuf_Duration_nanos(delay_duration)); + fault_injection_policy_json["delay"] = + ParseDuration(delay_duration).ToJsonString(); } // Set the headers if we enabled header delay injection control if (envoy_extensions_filters_common_fault_v3_FaultDelay_has_header_delay( diff --git a/src/core/lib/gprpp/time.cc b/src/core/lib/gprpp/time.cc index c7f02d5c2f9..00973b3f89c 100644 --- a/src/core/lib/gprpp/time.cc +++ b/src/core/lib/gprpp/time.cc @@ -21,6 +21,8 @@ #include #include +#include "absl/strings/str_format.h" + #include #include @@ -182,6 +184,11 @@ std::string Duration::ToString() const { return std::to_string(millis_) + "ms"; } +std::string Duration::ToJsonString() const { + gpr_timespec ts = as_timespec(); + return absl::StrFormat("%d.%09ds", ts.tv_sec, ts.tv_nsec); +} + void TestOnlySetProcessEpoch(gpr_timespec epoch) { g_process_epoch_seconds.store( gpr_convert_clock_type(epoch, GPR_CLOCK_MONOTONIC).tv_sec); diff --git a/src/core/lib/gprpp/time.h b/src/core/lib/gprpp/time.h index d4eacc14f69..3b695389734 100644 --- a/src/core/lib/gprpp/time.h +++ b/src/core/lib/gprpp/time.h @@ -211,6 +211,11 @@ class Duration { std::string ToString() const; + // Returns the duration in the JSON form corresponding to a + // google.protobuf.Duration proto, as defined here: + // https://developers.google.com/protocol-buffers/docs/proto3#json + std::string ToJsonString() const; + private: explicit constexpr Duration(int64_t millis) : millis_(millis) {}