• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2018 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 #ifndef GRPC_SRC_CORE_XDS_GRPC_XDS_ROUTE_CONFIG_H
18 #define GRPC_SRC_CORE_XDS_GRPC_XDS_ROUTE_CONFIG_H
19 
20 #include <stdint.h>
21 
22 #include <algorithm>
23 #include <map>
24 #include <memory>
25 #include <string>
26 #include <vector>
27 
28 #include "absl/types/optional.h"
29 #include "absl/types/variant.h"
30 #include "re2/re2.h"
31 #include "src/core/lib/channel/status_util.h"
32 #include "src/core/util/matchers.h"
33 #include "src/core/util/time.h"
34 #include "src/core/xds/grpc/xds_http_filter.h"
35 #include "src/core/xds/xds_client/xds_resource_type.h"
36 #include "src/core/xds/xds_client/xds_resource_type_impl.h"
37 
38 namespace grpc_core {
39 
40 struct XdsRouteConfigResource : public XdsResourceType::ResourceData {
41   using TypedPerFilterConfig =
42       std::map<std::string, XdsHttpFilterImpl::FilterConfig>;
43 
44   using ClusterSpecifierPluginMap =
45       std::map<std::string /*cluster_specifier_plugin_name*/,
46                std::string /*LB policy config*/>;
47 
48   struct RetryPolicy {
49     internal::StatusCodeSet retry_on;
50     uint32_t num_retries;
51 
52     struct RetryBackOff {
53       Duration base_interval;
54       Duration max_interval;
55 
56       bool operator==(const RetryBackOff& other) const {
57         return base_interval == other.base_interval &&
58                max_interval == other.max_interval;
59       }
60       std::string ToString() const;
61     };
62     RetryBackOff retry_back_off;
63 
64     bool operator==(const RetryPolicy& other) const {
65       return (retry_on == other.retry_on && num_retries == other.num_retries &&
66               retry_back_off == other.retry_back_off);
67     }
68     std::string ToString() const;
69   };
70 
71   struct Route {
72     // Matchers for this route.
73     struct Matchers {
74       StringMatcher path_matcher;
75       std::vector<HeaderMatcher> header_matchers;
76       absl::optional<uint32_t> fraction_per_million;
77 
78       bool operator==(const Matchers& other) const {
79         return path_matcher == other.path_matcher &&
80                header_matchers == other.header_matchers &&
81                fraction_per_million == other.fraction_per_million;
82       }
83       std::string ToString() const;
84     };
85 
86     Matchers matchers;
87 
88     struct UnknownAction {
89       bool operator==(const UnknownAction& /* other */) const { return true; }
90     };
91 
92     struct RouteAction {
93       struct HashPolicy {
94         struct Header {
95           std::string header_name;
96           std::unique_ptr<RE2> regex;
97           std::string regex_substitution;
98 
99           Header() = default;
100 
101           // Copyable.
102           Header(const Header& other);
103           Header& operator=(const Header& other);
104 
105           // Movable.
106           Header(Header&& other) noexcept;
107           Header& operator=(Header&& other) noexcept;
108 
109           bool operator==(const Header& other) const;
110           std::string ToString() const;
111         };
112 
113         struct ChannelId {
114           bool operator==(const ChannelId&) const { return true; }
115         };
116 
117         absl::variant<Header, ChannelId> policy;
118         bool terminal = false;
119 
120         bool operator==(const HashPolicy& other) const {
121           return policy == other.policy && terminal == other.terminal;
122         }
123         std::string ToString() const;
124       };
125 
126       struct ClusterName {
127         std::string cluster_name;
128 
129         bool operator==(const ClusterName& other) const {
130           return cluster_name == other.cluster_name;
131         }
132       };
133 
134       struct ClusterWeight {
135         std::string name;
136         uint32_t weight;
137         TypedPerFilterConfig typed_per_filter_config;
138 
139         bool operator==(const ClusterWeight& other) const {
140           return name == other.name && weight == other.weight &&
141                  typed_per_filter_config == other.typed_per_filter_config;
142         }
143         std::string ToString() const;
144       };
145 
146       struct ClusterSpecifierPluginName {
147         std::string cluster_specifier_plugin_name;
148 
149         bool operator==(const ClusterSpecifierPluginName& other) const {
150           return cluster_specifier_plugin_name ==
151                  other.cluster_specifier_plugin_name;
152         }
153       };
154 
155       std::vector<HashPolicy> hash_policies;
156       absl::optional<RetryPolicy> retry_policy;
157 
158       // Action for this route.
159       absl::variant<ClusterName, std::vector<ClusterWeight>,
160                     ClusterSpecifierPluginName>
161           action;
162 
163       // Storing the timeout duration from route action:
164       // RouteAction.max_stream_duration.grpc_timeout_header_max or
165       // RouteAction.max_stream_duration.max_stream_duration if the former is
166       // not set.
167       absl::optional<Duration> max_stream_duration;
168 
169       bool auto_host_rewrite = false;
170 
171       bool operator==(const RouteAction& other) const {
172         return hash_policies == other.hash_policies &&
173                retry_policy == other.retry_policy && action == other.action &&
174                max_stream_duration == other.max_stream_duration &&
175                auto_host_rewrite == other.auto_host_rewrite;
176       }
177       std::string ToString() const;
178     };
179 
180     struct NonForwardingAction {
181       bool operator==(const NonForwardingAction& /* other */) const {
182         return true;
183       }
184     };
185 
186     absl::variant<UnknownAction, RouteAction, NonForwardingAction> action;
187     TypedPerFilterConfig typed_per_filter_config;
188 
189     bool operator==(const Route& other) const {
190       return matchers == other.matchers && action == other.action &&
191              typed_per_filter_config == other.typed_per_filter_config;
192     }
193     std::string ToString() const;
194   };
195 
196   struct VirtualHost {
197     std::vector<std::string> domains;
198     std::vector<Route> routes;
199     TypedPerFilterConfig typed_per_filter_config;
200 
201     bool operator==(const VirtualHost& other) const {
202       return domains == other.domains && routes == other.routes &&
203              typed_per_filter_config == other.typed_per_filter_config;
204     }
205     std::string ToString() const;
206   };
207 
208   std::vector<VirtualHost> virtual_hosts;
209   ClusterSpecifierPluginMap cluster_specifier_plugin_map;
210 
211   bool operator==(const XdsRouteConfigResource& other) const {
212     return virtual_hosts == other.virtual_hosts &&
213            cluster_specifier_plugin_map == other.cluster_specifier_plugin_map;
214   }
215   std::string ToString() const;
216 };
217 
218 }  // namespace grpc_core
219 
220 #endif  // GRPC_SRC_CORE_XDS_GRPC_XDS_ROUTE_CONFIG_H
221