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

Code before:

using proto_processing_lib::proto_scrubber::FieldCheckerInterface;
using proto_processing_lib::proto_scrubber::FieldCheckResults;
using proto_processing_lib::proto_scrubber::FieldFilters;
using proto_processing_lib::proto_scrubber::ScrubberContext;

/**
 * FieldChecker class encapsulates the scrubbing logic of `ProtoApiScrubber` filter.
 * This `FieldChecker` would be integrated with `proto_processing_lib::proto_scrubber` library for
 * protobuf payload scrubbing. The `CheckField()` method declared in the parent class
 * `FieldCheckerInterface` and defined in this class is called by the
 * `proto_processing_lib::proto_scrubber` library for each field of the protobuf payload to decide
 * whether to preserve, remove or traverse it further.
 */
class FieldChecker : public FieldCheckerInterface, public Logger::Loggable<Logger::Id::filter> {
public:
  FieldChecker(const ScrubberContext scrubber_context,
               const Envoy::StreamInfo::StreamInfo* stream_info,
               const Http::RequestHeaderMap* request_headers,
               const Http::ResponseHeaderMap* response_headers,
               const Http::RequestTrailerMap* request_trailers,
               const Http::ResponseTrailerMap* response_trailers, const std::string& method_name,
               const ProtoApiScrubberFilterConfig* filter_config)
      : scrubber_context_(scrubber_context), matching_data_(*stream_info),
        method_name_(method_name), filter_config_ptr_(filter_config) {
    // Populate matching data with whatever is available.
    if (request_headers != nullptr) {
      matching_data_.onRequestHeaders(*request_headers);
    }
    if (response_headers != nullptr) {
      matching_data_.onResponseHeaders(*response_headers);
    }
    if (request_trailers != nullptr) {
      matching_data_.onRequestTrailers(*request_trailers);
    }
    if (response_trailers != nullptr) {
      matching_data_.onResponseTrailers(*response_trailers);
    }
  }

  // This type is neither copyable nor movable.
  FieldChecker(const FieldChecker&) = delete;
  FieldChecker& operator=(const FieldChecker&) = delete;
  ~FieldChecker() override {}

  // Make all the overloads from the base class visible here so the one explicit
  // override doesn't hide the other signatures.
  using FieldCheckerInterface::CheckField;

  /**
   * Returns whether the `field` should be included (kInclude), excluded (kExclude)

Review comment (suggestion):
FWIW, the design here seems a bit leaky (a single field checker for both request and response, but used differently for each). I guess that is ok for now, but if further divergence from behavior needs to be done for request/response, it may be best to divide the two paths to different classes.

Code after:

using proto_processing_lib::proto_scrubber::FieldCheckerInterface;
using proto_processing_lib::proto_scrubber::FieldCheckResults;
using proto_processing_lib::proto_scrubber::FieldFilters;
using proto_processing_lib::proto_scrubber::ScrubberContext;

/**
 * FieldChecker class encapsulates the scrubbing logic of `ProtoApiScrubber` filter.
 * This `FieldChecker` would be integrated with `proto_processing_lib::proto_scrubber` library for
 * protobuf payload scrubbing. The `CheckField()` method declared in the parent class
 * `FieldCheckerInterface` and defined in this class is called by the
 * `proto_processing_lib::proto_scrubber` library for each field of the protobuf payload to decide
 * whether to preserve, remove or traverse it further.
 */
class FieldChecker : public FieldCheckerInterface, public Logger::Loggable<Logger::Id::filter> {
public:
  FieldChecker(const ScrubberContext scrubber_context,
               const Envoy::StreamInfo::StreamInfo* stream_info,
               OptRef<const Http::RequestHeaderMap> request_headers,
               OptRef<const Http::ResponseHeaderMap> response_headers,
               OptRef<const Http::RequestTrailerMap> request_trailers,
               OptRef<const Http::ResponseTrailerMap> response_trailers,
               const std::string& method_name, const ProtoApiScrubberFilterConfig* filter_config)
      : scrubber_context_(scrubber_context), matching_data_(*stream_info),
        method_name_(method_name), filter_config_ptr_(filter_config) {
    if (request_headers.has_value()) {
      matching_data_.onRequestHeaders(request_headers.ref());
    }
    if (response_headers.has_value()) {
      matching_data_.onResponseHeaders(response_headers.ref());
    }
    if (request_trailers.has_value()) {
      matching_data_.onRequestTrailers(request_trailers.ref());
    }
    if (response_trailers.has_value()) {
      matching_data_.onResponseTrailers(response_trailers.ref());
    }
  }

  // This type is neither copyable nor movable.
  FieldChecker(const FieldChecker&) = delete;
  FieldChecker& operator=(const FieldChecker&) = delete;
  ~FieldChecker() override {}

  // Make all the overloads from the base class visible here so the one explicit
  // override doesn't hide the other signatures.
  using FieldCheckerInterface::CheckField;

  /**
   * Returns whether the `field` should be included (kInclude), excluded (kExclude)
   * or traversed further (kPartial).