1
#pragma once
2

            
3
#include "envoy/extensions/router/cluster_specifiers/matcher/v3/matcher.pb.h"
4
#include "envoy/router/cluster_specifier_plugin.h"
5

            
6
#include "source/common/matcher/matcher.h"
7

            
8
namespace Envoy {
9
namespace Extensions {
10
namespace Router {
11
namespace Matcher {
12

            
13
using MatcherClusterSpecifierConfigProto =
14
    envoy::extensions::router::cluster_specifiers::matcher::v3::MatcherClusterSpecifier;
15
using ClusterActionProto =
16
    envoy::extensions::router::cluster_specifiers::matcher::v3::ClusterAction;
17

            
18
/**
19
 * ClusterActionContext is used to construct ClusterAction. Empty struct because ClusterAction
20
 * doesn't need any context.
21
 */
22
struct ClusterActionContext {};
23

            
24
/**
25
 * ClusterAction is used to store the matched cluster name.
26
 */
27
class ClusterAction : public Envoy::Matcher::ActionBase<ClusterActionProto> {
28
public:
29
12
  explicit ClusterAction(absl::string_view cluster) : cluster_(cluster) {}
30

            
31
9
  const std::string& cluster() const { return cluster_; }
32

            
33
private:
34
  const std::string cluster_;
35
};
36

            
37
// Registered factory for ClusterAction. This factory will be used to load proto configuration
38
// from opaque config.
39
class ClusterActionFactory : public Envoy::Matcher::ActionFactory<ClusterActionContext> {
40
public:
41
  Envoy::Matcher::ActionConstSharedPtr
42
  createAction(const Protobuf::Message& config, ClusterActionContext& context,
43
               ProtobufMessage::ValidationVisitor& validation_visitor) override;
44
9
  std::string name() const override { return "cluster"; }
45
15
  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
46
15
    return std::make_unique<ClusterActionProto>();
47
15
  }
48
};
49
DECLARE_FACTORY(ClusterActionFactory);
50

            
51
/**
52
 * MatcherClusterSpecifierPlugin is the specific cluster specifier plugin. It will get the
53
 * target cluster name from the matched cluster action.
54
 */
55
class MatcherClusterSpecifierPlugin : public Envoy::Router::ClusterSpecifierPlugin,
56
                                      Logger::Loggable<Logger::Id::router> {
57
public:
58
  MatcherClusterSpecifierPlugin(
59
      Envoy::Matcher::MatchTreeSharedPtr<Http::HttpMatchingData> match_tree)
60
5
      : match_tree_(match_tree) {}
61
  Envoy::Router::RouteConstSharedPtr route(Envoy::Router::RouteEntryAndRouteConstSharedPtr parent,
62
                                           const Http::RequestHeaderMap& headers,
63
                                           const StreamInfo::StreamInfo& stream_info,
64
                                           uint64_t) const override;
65

            
66
private:
67
  Envoy::Matcher::MatchTreeSharedPtr<Http::HttpMatchingData> match_tree_;
68
};
69

            
70
} // namespace Matcher
71
} // namespace Router
72
} // namespace Extensions
73
} // namespace Envoy