-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ORCA: Added utility methods to parse ORCA response headers from backe…
…nds. (#35422) Signed-off-by: blake-snyder <blakesnyder@google.com>
- Loading branch information
1 parent
5b22dce
commit 603bc61
Showing
5 changed files
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_cc_library", | ||
"envoy_package", | ||
) | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
envoy_package() | ||
|
||
envoy_cc_library( | ||
name = "orca_parser", | ||
srcs = ["orca_parser.cc"], | ||
hdrs = ["orca_parser.h"], | ||
external_deps = [ | ||
"abseil_strings", | ||
"abseil_statusor", | ||
"fmtlib", | ||
], | ||
deps = [ | ||
"//envoy/http:header_map_interface", | ||
"//source/common/common:base64_lib", | ||
"@com_github_cncf_xds//xds/data/orca/v3:pkg_cc_proto", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include "source/common/orca/orca_parser.h" | ||
|
||
#include <string> | ||
|
||
#include "envoy/http/header_map.h" | ||
|
||
#include "source/common/common/base64.h" | ||
#include "source/common/common/fmt.h" | ||
|
||
#include "absl/strings/string_view.h" | ||
|
||
using ::Envoy::Http::HeaderMap; | ||
using xds::data::orca::v3::OrcaLoadReport; | ||
|
||
namespace Envoy { | ||
namespace Orca { | ||
|
||
namespace { | ||
|
||
const Http::LowerCaseString& endpointLoadMetricsHeaderBin() { | ||
CONSTRUCT_ON_FIRST_USE(Http::LowerCaseString, kEndpointLoadMetricsHeaderBin); | ||
} | ||
|
||
} // namespace | ||
|
||
absl::StatusOr<OrcaLoadReport> parseOrcaLoadReportHeaders(const HeaderMap& headers) { | ||
OrcaLoadReport load_report; | ||
|
||
// Binary protobuf format. | ||
if (const auto header_bin = headers.get(endpointLoadMetricsHeaderBin()); !header_bin.empty()) { | ||
const auto header_value = header_bin[0]->value().getStringView(); | ||
const std::string decoded_value = Envoy::Base64::decode(header_value); | ||
if (!load_report.ParseFromString(decoded_value)) { | ||
return absl::InvalidArgumentError( | ||
fmt::format("unable to parse binaryheader to OrcaLoadReport: {}", header_value)); | ||
} | ||
} else { | ||
return absl::NotFoundError("no ORCA data sent from the backend"); | ||
} | ||
|
||
return load_report; | ||
} | ||
|
||
} // namespace Orca | ||
} // namespace Envoy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#pragma once | ||
|
||
#include "envoy/http/header_map.h" | ||
|
||
#include "absl/status/statusor.h" | ||
#include "xds/data/orca/v3/orca_load_report.pb.h" | ||
|
||
namespace Envoy { | ||
namespace Orca { | ||
|
||
// Header used to send ORCA load metrics from the backend. | ||
static constexpr absl::string_view kEndpointLoadMetricsHeaderBin = "endpoint-load-metrics-bin"; | ||
|
||
// Parses ORCA load metrics from a header map into an OrcaLoadReport proto. | ||
// Supports serialized binary formats. | ||
absl::StatusOr<xds::data::orca::v3::OrcaLoadReport> | ||
parseOrcaLoadReportHeaders(const Envoy::Http::HeaderMap& headers); | ||
} // namespace Orca | ||
} // namespace Envoy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_cc_test", | ||
"envoy_package", | ||
) | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
envoy_package() | ||
|
||
envoy_cc_test( | ||
name = "orca_parser_test", | ||
srcs = ["orca_parser_test.cc"], | ||
external_deps = [ | ||
"abseil_status", | ||
"abseil_strings", | ||
"fmtlib", | ||
], | ||
deps = [ | ||
"//source/common/common:base64_lib", | ||
"//source/common/orca:orca_parser", | ||
"//test/test_common:status_utility_lib", | ||
"//test/test_common:utility_lib", | ||
"@com_github_cncf_xds//xds/data/orca/v3:pkg_cc_proto", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#include <string> | ||
|
||
#include "source/common/common/base64.h" | ||
#include "source/common/orca/orca_parser.h" | ||
|
||
#include "test/test_common/status_utility.h" | ||
#include "test/test_common/utility.h" | ||
|
||
#include "absl/status/status.h" | ||
#include "xds/data/orca/v3/orca_load_report.pb.h" | ||
|
||
namespace Envoy { | ||
namespace Orca { | ||
namespace { | ||
|
||
// Returns an example OrcaLoadReport proto with all fields populated. | ||
static xds::data::orca::v3::OrcaLoadReport exampleOrcaLoadReport() { | ||
xds::data::orca::v3::OrcaLoadReport orca_load_report; | ||
orca_load_report.set_cpu_utilization(0.7); | ||
orca_load_report.set_application_utilization(0.8); | ||
orca_load_report.set_mem_utilization(0.9); | ||
orca_load_report.set_eps(2); | ||
orca_load_report.set_rps_fractional(1000); | ||
orca_load_report.mutable_named_metrics()->insert({"foo", 123}); | ||
orca_load_report.mutable_named_metrics()->insert({"bar", 0.2}); | ||
return orca_load_report; | ||
} | ||
|
||
TEST(OrcaParserUtilTest, NoHeaders) { | ||
Http::TestRequestHeaderMapImpl headers{}; | ||
// parseOrcaLoadReport returns error when no ORCA data is sent from | ||
// the backend. | ||
EXPECT_THAT(parseOrcaLoadReportHeaders(headers), | ||
StatusHelpers::HasStatus(absl::NotFoundError("no ORCA data sent from the backend"))); | ||
} | ||
|
||
TEST(OrcaParserUtilTest, MissingOrcaHeaders) { | ||
Http::TestRequestHeaderMapImpl headers{{"wrong-header", "wrong-value"}}; | ||
// parseOrcaLoadReport returns error when no ORCA data is sent from | ||
// the backend. | ||
EXPECT_THAT(parseOrcaLoadReportHeaders(headers), | ||
StatusHelpers::HasStatus(absl::NotFoundError("no ORCA data sent from the backend"))); | ||
} | ||
|
||
TEST(OrcaParserUtilTest, BinaryHeader) { | ||
const std::string proto_string = | ||
TestUtility::getProtobufBinaryStringFromMessage(exampleOrcaLoadReport()); | ||
const auto orca_load_report_header_bin = | ||
Envoy::Base64::encode(proto_string.c_str(), proto_string.length()); | ||
Http::TestRequestHeaderMapImpl headers{ | ||
{std::string(kEndpointLoadMetricsHeaderBin), orca_load_report_header_bin}}; | ||
EXPECT_THAT(parseOrcaLoadReportHeaders(headers), | ||
StatusHelpers::IsOkAndHolds(ProtoEq(exampleOrcaLoadReport()))); | ||
} | ||
|
||
TEST(OrcaParserUtilTest, InvalidBinaryHeader) { | ||
const std::string proto_string = | ||
TestUtility::getProtobufBinaryStringFromMessage(exampleOrcaLoadReport()); | ||
// Force a bad base64 encoding by shortening the length of the output. | ||
const auto orca_load_report_header_bin = | ||
Envoy::Base64::encode(proto_string.c_str(), proto_string.length() / 2); | ||
Http::TestRequestHeaderMapImpl headers{ | ||
{std::string(kEndpointLoadMetricsHeaderBin), orca_load_report_header_bin}}; | ||
EXPECT_THAT(parseOrcaLoadReportHeaders(headers), | ||
StatusHelpers::HasStatus( | ||
absl::StatusCode::kInvalidArgument, | ||
testing::HasSubstr("unable to parse binaryheader to OrcaLoadReport"))); | ||
} | ||
|
||
} // namespace | ||
} // namespace Orca | ||
} // namespace Envoy |