Repository: envoyproxy/envoy
File: source/extensions/filters/http/stateful_session/stateful_session.h (C/C++)

Code before:
 */
#define ALL_STATEFUL_SESSION_FILTER_STATS(COUNTER)                                                 \
  COUNTER(routed)                                                                                  \
  COUNTER(failed_open)                                                                             \
  COUNTER(failed_closed)

/**
 * Wrapper struct for Stateful Session filter stats. @see stats_macros.h
 */
struct StatefulSessionFilterStats {
  ALL_STATEFUL_SESSION_FILTER_STATS(GENERATE_COUNTER_STRUCT)
};

class StatefulSessionConfig {
public:
  StatefulSessionConfig(const ProtoConfig& config,
                        Server::Configuration::GenericFactoryContext& context);

  Http::SessionStatePtr createSessionState(Http::RequestHeaderMap& headers) const {
    ASSERT(factory_ != nullptr);
    return factory_->create(headers);
  }

  bool isStrict() const { return strict_; }

  const std::string& statPrefixOverride() const { return stat_prefix_override_; }

  void setStats(const std::shared_ptr<StatefulSessionFilterStats>& stats) { stats_ = stats; }
  const std::shared_ptr<StatefulSessionFilterStats>& stats() const { return stats_; }

private:
  Http::SessionStateFactorySharedPtr factory_;
  bool strict_{false};
  std::string stat_prefix_override_{};
  std::shared_ptr<StatefulSessionFilterStats> stats_{};
};
using StatefulSessionConfigSharedPtr = std::shared_ptr<StatefulSessionConfig>;

class PerRouteStatefulSession : public Router::RouteSpecificFilterConfig {
public:
  PerRouteStatefulSession(const PerRouteProtoConfig& config,
                          Server::Configuration::GenericFactoryContext& context);

  bool disabled() const { return disabled_; }
  StatefulSessionConfig* statefulSessionConfig() const { return config_.get(); }

private:
  bool disabled_{};
  StatefulSessionConfigSharedPtr config_;
};
using PerRouteStatefulSessionConfigSharedPtr = std::shared_ptr<PerRouteStatefulSession>;

Review comment (suggestion):
Actually, I think you should construct the stats in the constructor of the `StatefulSessionConfig`. And if the stat_prefix is not set, the stats will not be generated. If the stat_prefix is set, we will construct the stats and use a method to return an optional reference to the stats.

Note, for now no matter stats prefix is set or not, the stats will be generated, but I think this is undefined in our API comments and may keep no stats in that case.

Code after:
 * All stats for the Stateful Session filter. @see stats_macros.h
 */
#define ALL_STATEFUL_SESSION_FILTER_STATS(COUNTER)                                                 \
  COUNTER(routed)                                                                                  \
  COUNTER(failed_open)                                                                             \
  COUNTER(failed_closed)

/**
 * Wrapper struct for Stateful Session filter stats. @see stats_macros.h
 */
struct StatefulSessionFilterStats {
  ALL_STATEFUL_SESSION_FILTER_STATS(GENERATE_COUNTER_STRUCT)
};

class StatefulSessionConfig {
public:
  StatefulSessionConfig(const ProtoConfig& config,
                        Server::Configuration::GenericFactoryContext& context,
                        const std::string& stats_prefix, Stats::Scope& scope);

  Http::SessionStatePtr createSessionState(Http::RequestHeaderMap& headers) const {
    ASSERT(factory_ != nullptr);
    return factory_->create(headers);
  }

  bool isStrict() const { return strict_; }

  OptRef<StatefulSessionFilterStats> stats() { return makeOptRefFromPtr(stats_.get()); }

private:
  Http::SessionStateFactorySharedPtr factory_;
  bool strict_{false};
  std::shared_ptr<StatefulSessionFilterStats> stats_;
};
using StatefulSessionConfigSharedPtr = std::shared_ptr<StatefulSessionConfig>;

class PerRouteStatefulSession : public Router::RouteSpecificFilterConfig {
public:
  PerRouteStatefulSession(const PerRouteProtoConfig& config,
                          Server::Configuration::GenericFactoryContext& context);

  bool disabled() const { return disabled_; }
  StatefulSessionConfig* statefulSessionConfig() const { return config_.get(); }

private:
  bool disabled_{};
  StatefulSessionConfigSharedPtr config_;
};
using PerRouteStatefulSessionConfigSharedPtr = std::shared_ptr<PerRouteStatefulSession>;

class StatefulSession : public Http::PassThroughFilter,