1
#include "source/extensions/load_balancing_policies/dynamic_modules/lb_config.h"
2

            
3
#include "absl/strings/str_cat.h"
4

            
5
namespace Envoy {
6
namespace Extensions {
7
namespace LoadBalancingPolicies {
8
namespace DynamicModules {
9

            
10
absl::StatusOr<DynamicModuleLbConfigSharedPtr>
11
DynamicModuleLbConfig::create(const std::string& lb_policy_name, const std::string& lb_config,
12
                              const std::string& metrics_namespace,
13
                              Envoy::Extensions::DynamicModules::DynamicModulePtr module,
14
48
                              Stats::Scope& stats_scope) {
15
48
  std::shared_ptr<DynamicModuleLbConfig> config(new DynamicModuleLbConfig(
16
48
      lb_policy_name, lb_config, metrics_namespace, std::move(module), stats_scope));
17

            
18
  // Resolve all required function pointers from the dynamic module.
19
48
#define RESOLVE_SYMBOL(name, type, member)                                                         \
20
286
  {                                                                                                \
21
286
    auto symbol_or_error = config->dynamic_module_->getFunctionPointer<type>(name);                \
22
286
    if (!symbol_or_error.ok()) {                                                                   \
23
1
      return symbol_or_error.status();                                                             \
24
1
    }                                                                                              \
25
286
    config->member = symbol_or_error.value();                                                      \
26
285
  }
27

            
28
48
  RESOLVE_SYMBOL("envoy_dynamic_module_on_lb_config_new", OnLbConfigNewType, on_config_new_);
29
48
  RESOLVE_SYMBOL("envoy_dynamic_module_on_lb_config_destroy", OnLbConfigDestroyType,
30
48
                 on_config_destroy_);
31
48
  RESOLVE_SYMBOL("envoy_dynamic_module_on_lb_new", OnLbNewType, on_lb_new_);
32
48
  RESOLVE_SYMBOL("envoy_dynamic_module_on_lb_choose_host", OnLbChooseHostType, on_choose_host_);
33
47
  RESOLVE_SYMBOL("envoy_dynamic_module_on_lb_on_host_membership_update",
34
47
                 OnLbOnHostMembershipUpdateType, on_host_membership_update_);
35
47
  RESOLVE_SYMBOL("envoy_dynamic_module_on_lb_destroy", OnLbDestroyType, on_lb_destroy_);
36

            
37
47
#undef RESOLVE_SYMBOL
38

            
39
  // Call on_config_new to get the in-module configuration. The module can call
40
  // metric-defining callbacks during this invocation.
41
47
  envoy_dynamic_module_type_envoy_buffer name_buffer = {config->lb_policy_name_.data(),
42
47
                                                        config->lb_policy_name_.size()};
43
47
  envoy_dynamic_module_type_envoy_buffer config_buffer = {config->lb_config_.data(),
44
47
                                                          config->lb_config_.size()};
45

            
46
47
  config->in_module_config_ = config->on_config_new_(config.get(), name_buffer, config_buffer);
47
47
  if (config->in_module_config_ == nullptr) {
48
1
    return absl::InvalidArgumentError("failed to create in-module load balancer configuration");
49
1
  }
50

            
51
46
  return config;
52
47
}
53

            
54
DynamicModuleLbConfig::DynamicModuleLbConfig(
55
    const std::string& lb_policy_name, const std::string& lb_config,
56
    const std::string& metrics_namespace,
57
    Envoy::Extensions::DynamicModules::DynamicModulePtr dynamic_module, Stats::Scope& stats_scope)
58
48
    : in_module_config_(nullptr),
59
48
      stats_scope_(stats_scope.createScope(absl::StrCat(metrics_namespace, "."))),
60
48
      stat_name_pool_(stats_scope_->symbolTable()), lb_policy_name_(lb_policy_name),
61
48
      lb_config_(lb_config), dynamic_module_(std::move(dynamic_module)) {}
62

            
63
48
DynamicModuleLbConfig::~DynamicModuleLbConfig() {
64
48
  if (in_module_config_ != nullptr && on_config_destroy_ != nullptr) {
65
46
    on_config_destroy_(in_module_config_);
66
46
  }
67
48
}
68

            
69
} // namespace DynamicModules
70
} // namespace LoadBalancingPolicies
71
} // namespace Extensions
72
} // namespace Envoy