• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2020 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include <grpc/support/port_platform.h>
18 
19 #include "src/core/ext/filters/client_channel/lb_policy/address_filtering.h"
20 
21 #include "absl/strings/str_cat.h"
22 #include "absl/strings/str_join.h"
23 
24 #include "src/core/lib/channel/channel_args.h"
25 
26 #define GRPC_ARG_HIERARCHICAL_PATH "grpc.internal.address.hierarchical_path"
27 
28 namespace grpc_core {
29 
30 const char* kHierarchicalPathAttributeKey = "hierarchical_path";
31 
32 namespace {
33 
34 class HierarchicalPathAttribute : public ServerAddress::AttributeInterface {
35  public:
HierarchicalPathAttribute(std::vector<std::string> path)36   explicit HierarchicalPathAttribute(std::vector<std::string> path)
37       : path_(std::move(path)) {}
38 
Copy() const39   std::unique_ptr<AttributeInterface> Copy() const override {
40     return absl::make_unique<HierarchicalPathAttribute>(path_);
41   }
42 
Cmp(const AttributeInterface * other) const43   int Cmp(const AttributeInterface* other) const override {
44     const std::vector<std::string>& other_path =
45         static_cast<const HierarchicalPathAttribute*>(other)->path_;
46     for (size_t i = 0; i < path_.size(); ++i) {
47       if (other_path.size() == i) return 1;
48       int r = path_[i].compare(other_path[i]);
49       if (r != 0) return r;
50     }
51     if (other_path.size() > path_.size()) return -1;
52     return 0;
53   }
54 
ToString() const55   std::string ToString() const override {
56     return absl::StrCat("[", absl::StrJoin(path_, ", "), "]");
57   }
58 
path() const59   const std::vector<std::string>& path() const { return path_; }
60 
61  private:
62   std::vector<std::string> path_;
63 };
64 
65 }  // namespace
66 
67 std::unique_ptr<ServerAddress::AttributeInterface>
MakeHierarchicalPathAttribute(std::vector<std::string> path)68 MakeHierarchicalPathAttribute(std::vector<std::string> path) {
69   return absl::make_unique<HierarchicalPathAttribute>(std::move(path));
70 }
71 
MakeHierarchicalAddressMap(const ServerAddressList & addresses)72 HierarchicalAddressMap MakeHierarchicalAddressMap(
73     const ServerAddressList& addresses) {
74   HierarchicalAddressMap result;
75   for (const ServerAddress& address : addresses) {
76     const HierarchicalPathAttribute* path_attribute =
77         static_cast<const HierarchicalPathAttribute*>(
78             address.GetAttribute(kHierarchicalPathAttributeKey));
79     if (path_attribute == nullptr) continue;
80     const std::vector<std::string>& path = path_attribute->path();
81     auto it = path.begin();
82     ServerAddressList& target_list = result[*it];
83     std::unique_ptr<HierarchicalPathAttribute> new_attribute;
84     ++it;
85     if (it != path.end()) {
86       std::vector<std::string> remaining_path(it, path.end());
87       new_attribute = absl::make_unique<HierarchicalPathAttribute>(
88           std::move(remaining_path));
89     }
90     target_list.emplace_back(address.WithAttribute(
91         kHierarchicalPathAttributeKey, std::move(new_attribute)));
92   }
93   return result;
94 }
95 
96 }  // namespace grpc_core
97