blob: 5abdd081e2404447d0dc6ae72bab38f044c9a8be [file]
//
// Copyright 2018 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef GRPC_CORE_EXT_XDS_XDS_ROUTE_CONFIG_H
#define GRPC_CORE_EXT_XDS_XDS_ROUTE_CONFIG_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "envoy/config/route/v3/route.upb.h"
#include "envoy/config/route/v3/route.upbdefs.h"
#include "re2/re2.h"
#include "upb/def.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_cluster_specifier_plugin.h"
#include "src/core/ext/xds/xds_http_filters.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/matchers/matchers.h"
namespace grpc_core {
bool XdsRbacEnabled();
struct XdsRouteConfigResource {
using TypedPerFilterConfig =
std::map<std::string, XdsHttpFilterImpl::FilterConfig>;
struct RetryPolicy {
internal::StatusCodeSet retry_on;
uint32_t num_retries;
struct RetryBackOff {
Duration base_interval;
Duration max_interval;
bool operator==(const RetryBackOff& other) const {
return base_interval == other.base_interval &&
max_interval == other.max_interval;
}
std::string ToString() const;
};
RetryBackOff retry_back_off;
bool operator==(const RetryPolicy& other) const {
return (retry_on == other.retry_on && num_retries == other.num_retries &&
retry_back_off == other.retry_back_off);
}
std::string ToString() const;
};
struct Route {
// Matchers for this route.
struct Matchers {
StringMatcher path_matcher;
std::vector<HeaderMatcher> header_matchers;
absl::optional<uint32_t> fraction_per_million;
bool operator==(const Matchers& other) const {
return path_matcher == other.path_matcher &&
header_matchers == other.header_matchers &&
fraction_per_million == other.fraction_per_million;
}
std::string ToString() const;
};
Matchers matchers;
struct UnknownAction {
bool operator==(const UnknownAction& /* other */) const { return true; }
};
struct RouteAction {
struct HashPolicy {
enum Type { HEADER, CHANNEL_ID };
Type type;
bool terminal = false;
// Fields used for type HEADER.
std::string header_name;
std::unique_ptr<RE2> regex = nullptr;
std::string regex_substitution;
HashPolicy() {}
// Copyable.
HashPolicy(const HashPolicy& other);
HashPolicy& operator=(const HashPolicy& other);
// Moveable.
HashPolicy(HashPolicy&& other) noexcept;
HashPolicy& operator=(HashPolicy&& other) noexcept;
bool operator==(const HashPolicy& other) const;
std::string ToString() const;
};
struct ClusterWeight {
std::string name;
uint32_t weight;
TypedPerFilterConfig typed_per_filter_config;
bool operator==(const ClusterWeight& other) const {
return name == other.name && weight == other.weight &&
typed_per_filter_config == other.typed_per_filter_config;
}
std::string ToString() const;
};
std::vector<HashPolicy> hash_policies;
absl::optional<RetryPolicy> retry_policy;
// Action for this route.
static constexpr size_t kClusterIndex = 0;
static constexpr size_t kWeightedClustersIndex = 1;
static constexpr size_t kClusterSpecifierPluginIndex = 2;
absl::variant<std::string, std::vector<ClusterWeight>, std::string>
action;
// Storing the timeout duration from route action:
// RouteAction.max_stream_duration.grpc_timeout_header_max or
// RouteAction.max_stream_duration.max_stream_duration if the former is
// not set.
absl::optional<Duration> max_stream_duration;
bool operator==(const RouteAction& other) const {
return hash_policies == other.hash_policies &&
retry_policy == other.retry_policy && action == other.action &&
max_stream_duration == other.max_stream_duration;
}
std::string ToString() const;
};
struct NonForwardingAction {
bool operator==(const NonForwardingAction& /* other */) const {
return true;
}
};
absl::variant<UnknownAction, RouteAction, NonForwardingAction> action;
TypedPerFilterConfig typed_per_filter_config;
bool operator==(const Route& other) const {
return matchers == other.matchers && action == other.action &&
typed_per_filter_config == other.typed_per_filter_config;
}
std::string ToString() const;
};
struct VirtualHost {
std::vector<std::string> domains;
std::vector<Route> routes;
TypedPerFilterConfig typed_per_filter_config;
bool operator==(const VirtualHost& other) const {
return domains == other.domains && routes == other.routes &&
typed_per_filter_config == other.typed_per_filter_config;
}
};
std::vector<VirtualHost> virtual_hosts;
std::map<std::string /*cluster_specifier_plugin_name*/,
std::string /*LB policy config*/>
cluster_specifier_plugin_map;
bool operator==(const XdsRouteConfigResource& other) const {
return virtual_hosts == other.virtual_hosts &&
cluster_specifier_plugin_map == other.cluster_specifier_plugin_map;
}
std::string ToString() const;
static grpc_error_handle Parse(
const XdsEncodingContext& context,
const envoy_config_route_v3_RouteConfiguration* route_config,
XdsRouteConfigResource* rds_update);
};
class XdsRouteConfigResourceType
: public XdsResourceTypeImpl<XdsRouteConfigResourceType,
XdsRouteConfigResource> {
public:
absl::string_view type_url() const override {
return "envoy.config.route.v3.RouteConfiguration";
}
absl::string_view v2_type_url() const override {
return "envoy.api.v2.RouteConfiguration";
}
absl::StatusOr<DecodeResult> Decode(const XdsEncodingContext& context,
absl::string_view serialized_resource,
bool /*is_v2*/) const override;
void InitUpbSymtab(upb_DefPool* symtab) const override {
envoy_config_route_v3_RouteConfiguration_getmsgdef(symtab);
XdsClusterSpecifierPluginRegistry::PopulateSymtab(symtab);
}
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_XDS_XDS_ROUTE_CONFIG_H