1 // Copyright 2024 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <grpc/support/port_platform.h>
16
17 #include "src/core/ext/transport/chaotic_good/settings_metadata.h"
18
19 #include "absl/status/status.h"
20
21 #include "src/core/lib/gprpp/crash.h"
22
23 namespace grpc_core {
24 namespace chaotic_good {
25
ToMetadataBatch()26 Arena::PoolPtr<grpc_metadata_batch> SettingsMetadata::ToMetadataBatch() {
27 auto md = Arena::MakePooled<grpc_metadata_batch>();
28 auto add = [&md](absl::string_view key, std::string value) {
29 md->Append(key, Slice::FromCopiedString(value),
30 [key, value](absl::string_view error, const Slice&) {
31 Crash(absl::StrCat("Failed to add metadata '", key, "' = '",
32 value, "': ", error));
33 });
34 };
35 if (connection_type.has_value()) {
36 add("chaotic-good-connection-type",
37 connection_type.value() == ConnectionType::kControl ? "control"
38 : "data");
39 }
40 if (connection_id.has_value()) {
41 add("chaotic-good-connection-id", connection_id.value());
42 }
43 if (alignment.has_value()) {
44 add("chaotic-good-alignment", absl::StrCat(alignment.value()));
45 }
46 return md;
47 }
48
FromMetadataBatch(const grpc_metadata_batch & batch)49 absl::StatusOr<SettingsMetadata> SettingsMetadata::FromMetadataBatch(
50 const grpc_metadata_batch& batch) {
51 SettingsMetadata md;
52 std::string buffer;
53 auto v = batch.GetStringValue("chaotic-good-connection-type", &buffer);
54 if (v.has_value()) {
55 if (*v == "control") {
56 md.connection_type = ConnectionType::kControl;
57 } else if (*v == "data") {
58 md.connection_type = ConnectionType::kData;
59 } else {
60 return absl::UnavailableError(
61 absl::StrCat("Invalid connection type: ", *v));
62 }
63 }
64 v = batch.GetStringValue("chaotic-good-connection-id", &buffer);
65 if (v.has_value()) {
66 md.connection_id = std::string(*v);
67 }
68 v = batch.GetStringValue("chaotic-good-alignment", &buffer);
69 if (v.has_value()) {
70 uint32_t alignment;
71 if (!absl::SimpleAtoi(*v, &alignment)) {
72 return absl::UnavailableError(absl::StrCat("Invalid alignment: ", *v));
73 }
74 md.alignment = alignment;
75 }
76 return md;
77 }
78
79 } // namespace chaotic_good
80 } // namespace grpc_core
81