Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/filters/network/dubbo_proxy/config.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/extensions/filters/network/dubbo_proxy/config.h"
2
3
#include "envoy/extensions/filters/network/dubbo_proxy/v3/dubbo_proxy.pb.h"
4
#include "envoy/extensions/filters/network/dubbo_proxy/v3/dubbo_proxy.pb.validate.h"
5
#include "envoy/registry/registry.h"
6
7
#include "source/common/config/utility.h"
8
#include "source/extensions/filters/network/dubbo_proxy/conn_manager.h"
9
#include "source/extensions/filters/network/dubbo_proxy/filters/factory_base.h"
10
#include "source/extensions/filters/network/dubbo_proxy/router/rds.h"
11
#include "source/extensions/filters/network/dubbo_proxy/router/rds_impl.h"
12
#include "source/extensions/filters/network/dubbo_proxy/stats.h"
13
14
#include "absl/container/flat_hash_map.h"
15
16
namespace Envoy {
17
namespace Extensions {
18
namespace NetworkFilters {
19
namespace DubboProxy {
20
21
SINGLETON_MANAGER_REGISTRATION(dubbo_route_config_provider_manager);
22
23
Network::FilterFactoryCb DubboProxyFilterConfigFactory::createFilterFactoryFromProtoTyped(
24
    const envoy::extensions::filters::network::dubbo_proxy::v3::DubboProxy& proto_config,
25
0
    Server::Configuration::FactoryContext& context) {
26
0
  std::shared_ptr<Router::RouteConfigProviderManager> route_config_provider_manager =
27
0
      context.singletonManager().getTyped<Router::RouteConfigProviderManager>(
28
0
          SINGLETON_MANAGER_REGISTERED_NAME(dubbo_route_config_provider_manager), [&context] {
29
0
            return std::make_shared<Router::RouteConfigProviderManagerImpl>(context.admin());
30
0
          });
31
32
0
  std::shared_ptr<Config> filter_config(
33
0
      std::make_shared<ConfigImpl>(proto_config, context, *route_config_provider_manager));
34
35
0
  return [route_config_provider_manager, filter_config,
36
0
          &context](Network::FilterManager& filter_manager) -> void {
37
0
    filter_manager.addReadFilter(
38
0
        std::make_shared<ConnectionManager>(*filter_config, context.api().randomGenerator(),
39
0
                                            context.mainThreadDispatcher().timeSource()));
40
0
  };
41
0
}
42
43
/**
44
 * Static registration for the dubbo filter. @see RegisterFactory.
45
 */
46
REGISTER_FACTORY(DubboProxyFilterConfigFactory,
47
                 Server::Configuration::NamedNetworkFilterConfigFactory);
48
49
class ProtocolTypeMapper {
50
public:
51
  using ConfigProtocolType = envoy::extensions::filters::network::dubbo_proxy::v3::ProtocolType;
52
  using ProtocolTypeMap = absl::flat_hash_map<ConfigProtocolType, ProtocolType>;
53
54
0
  static ProtocolType lookupProtocolType(ConfigProtocolType config_type) {
55
0
    const auto& iter = protocolTypeMap().find(config_type);
56
0
    ASSERT(iter != protocolTypeMap().end());
57
0
    return iter->second;
58
0
  }
59
60
private:
61
0
  static const ProtocolTypeMap& protocolTypeMap() {
62
0
    CONSTRUCT_ON_FIRST_USE(ProtocolTypeMap, {
63
0
                                                {ConfigProtocolType::Dubbo, ProtocolType::Dubbo},
64
0
                                            });
65
0
  }
66
};
67
68
class SerializationTypeMapper {
69
public:
70
  using ConfigSerializationType =
71
      envoy::extensions::filters::network::dubbo_proxy::v3::SerializationType;
72
  using SerializationTypeMap = absl::flat_hash_map<ConfigSerializationType, SerializationType>;
73
74
0
  static SerializationType lookupSerializationType(ConfigSerializationType type) {
75
0
    const auto& iter = serializationTypeMap().find(type);
76
0
    ASSERT(iter != serializationTypeMap().end());
77
0
    return iter->second;
78
0
  }
79
80
private:
81
0
  static const SerializationTypeMap& serializationTypeMap() {
82
0
    CONSTRUCT_ON_FIRST_USE(SerializationTypeMap,
83
0
                           {
84
0
                               {ConfigSerializationType::Hessian2, SerializationType::Hessian2},
85
0
                           });
86
0
  }
87
};
88
89
// class ConfigImpl.
90
ConfigImpl::ConfigImpl(const DubboProxyConfig& config,
91
                       Server::Configuration::FactoryContext& context,
92
                       Router::RouteConfigProviderManager& route_config_provider_manager)
93
    : context_(context), stats_prefix_(fmt::format("dubbo.{}.", config.stat_prefix())),
94
      stats_(DubboFilterStats::generateStats(stats_prefix_, context_.scope())),
95
      serialization_type_(
96
          SerializationTypeMapper::lookupSerializationType(config.serialization_type())),
97
0
      protocol_type_(ProtocolTypeMapper::lookupProtocolType(config.protocol_type())) {
98
99
0
  if (config.has_drds()) {
100
0
    if (config.route_config_size() > 0) {
101
0
      throw EnvoyException("both drds and route_config is present in DubboProxy");
102
0
    }
103
0
    if (config.drds().config_source().config_source_specifier_case() ==
104
0
        envoy::config::core::v3::ConfigSource::kApiConfigSource) {
105
0
      const auto api_type = config.drds().config_source().api_config_source().api_type();
106
0
      if (api_type != envoy::config::core::v3::ApiConfigSource::AGGREGATED_GRPC &&
107
0
          api_type != envoy::config::core::v3::ApiConfigSource::AGGREGATED_DELTA_GRPC) {
108
0
        throw EnvoyException("drds supports only aggregated api_type in api_config_source");
109
0
      }
110
0
    }
111
0
    route_config_provider_ = route_config_provider_manager.createRdsRouteConfigProvider(
112
0
        config.drds(), context_.getServerFactoryContext(), stats_prefix_, context_.initManager());
113
0
  } else if (config.has_multiple_route_config()) {
114
0
    if (config.route_config_size() > 0) {
115
0
      throw EnvoyException("both mutiple_route_config and route_config is present in DubboProxy");
116
0
    }
117
0
    route_config_provider_ = route_config_provider_manager.createStaticRouteConfigProvider(
118
0
        config.multiple_route_config(), context_.getServerFactoryContext());
119
0
  } else {
120
0
    envoy::extensions::filters::network::dubbo_proxy::v3::MultipleRouteConfiguration
121
0
        multiple_route_config;
122
123
0
    *multiple_route_config.mutable_route_config() = config.route_config();
124
0
    route_config_provider_ = route_config_provider_manager.createStaticRouteConfigProvider(
125
0
        multiple_route_config, context_.getServerFactoryContext());
126
0
  }
127
128
0
  if (config.dubbo_filters().empty()) {
129
0
    ENVOY_LOG(debug, "using default router filter");
130
131
0
    envoy::extensions::filters::network::dubbo_proxy::v3::DubboFilter router_config;
132
0
    router_config.set_name("envoy.filters.dubbo.router");
133
0
    registerFilter(router_config);
134
0
  } else {
135
0
    for (const auto& filter_config : config.dubbo_filters()) {
136
0
      registerFilter(filter_config);
137
0
    }
138
0
  }
139
0
}
140
141
0
void ConfigImpl::createFilterChain(DubboFilters::FilterChainFactoryCallbacks& callbacks) {
142
0
  for (const DubboFilters::FilterFactoryCb& factory : filter_factories_) {
143
0
    factory(callbacks);
144
0
  }
145
0
}
146
147
Router::RouteConstSharedPtr ConfigImpl::route(const MessageMetadata& metadata,
148
0
                                              uint64_t random_value) const {
149
0
  auto config = std::static_pointer_cast<const Router::Config>(route_config_provider_->config());
150
0
  return config->route(metadata, random_value);
151
0
}
152
153
0
ProtocolPtr ConfigImpl::createProtocol() {
154
0
  return NamedProtocolConfigFactory::getFactory(protocol_type_).createProtocol(serialization_type_);
155
0
}
156
157
0
void ConfigImpl::registerFilter(const DubboFilterConfig& proto_config) {
158
0
  const auto& string_name = proto_config.name();
159
0
  ENVOY_LOG(debug, "    dubbo filter #{}", filter_factories_.size());
160
0
  ENVOY_LOG(debug, "      name: {}", string_name);
161
0
  ENVOY_LOG(debug, "    config: {}",
162
0
            MessageUtil::getJsonStringFromMessageOrError(proto_config.config()));
163
164
0
  auto& factory =
165
0
      Envoy::Config::Utility::getAndCheckFactoryByName<DubboFilters::NamedDubboFilterConfigFactory>(
166
0
          string_name);
167
0
  ProtobufTypes::MessagePtr message = factory.createEmptyConfigProto();
168
0
  Envoy::Config::Utility::translateOpaqueConfig(proto_config.config(),
169
0
                                                context_.messageValidationVisitor(), *message);
170
0
  DubboFilters::FilterFactoryCb callback =
171
0
      factory.createFilterFactoryFromProto(*message, stats_prefix_, context_);
172
173
0
  filter_factories_.push_back(callback);
174
0
}
175
176
} // namespace DubboProxy
177
} // namespace NetworkFilters
178
} // namespace Extensions
179
} // namespace Envoy