| /** @file |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| #pragma once |
| |
| #include <iostream> |
| #include <yaml-cpp/yaml.h> |
| |
| #include "shared/rpc/RPCRequests.h" |
| |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| /// |
| /// Base class that implements the basic output format. |
| /// |
| /// Every command will print out specific details depending on the nature of the message. This base class models the basic API. |
| /// @c _format member should be set when the object is created, this member should be used to decide the way we want to generate |
| /// the output and possibly(TODO) where we want it(stdout, stderr, etc.). If no output is needed GenericPrinter can be used which is |
| /// muted. |
| class BasePrinter |
| { |
| public: |
| /// This enum maps the --format flag coming from traffic_ctl. (also --records is included here, see comments down below.) |
| struct Options { |
| enum class OutputFormat { |
| LEGACY = 0, // Legacy format, mimics the old traffic_ctl output |
| PRETTY, // Enhanced printing messages. (in case you would like to generate them) |
| JSON, // Json formatting |
| RECORDS, // only valid for configs, but it's handy to have it here. |
| RPC // Print JSONRPC request and response + default output. |
| }; |
| Options() = default; |
| Options(OutputFormat fmt) : _format(fmt) {} |
| OutputFormat _format{OutputFormat::LEGACY}; //!< selected(passed) format. |
| }; |
| |
| /// Printer constructor. Needs the format as it will be used by derived classes. |
| BasePrinter(Options opts) : _printOpt(opts) {} |
| |
| BasePrinter() = default; |
| virtual ~BasePrinter() = default; |
| |
| /// |
| /// Function that will generate the expected output based on the response result. |
| /// |
| /// If the response contains any high level error, it will be print and the the specific derived class @c write_output() will not |
| /// be called. |
| /// @param response the server response. |
| /// |
| void write_output(shared::rpc::JSONRPCResponse const &response); |
| |
| /// |
| /// Write output based on the response values. |
| /// |
| /// Implement this one so you deal with the expected output, @c _format will be already set to the right |
| /// selected type so you can decide what to print. |
| /// |
| /// @param result jsonrpc result structure. No format specified by us, it's the one specified by the actual jsonrpc |
| /// response. |
| /// |
| virtual void write_output(YAML::Node const &result) = 0; |
| |
| virtual void write_output(std::string_view output) const; |
| virtual void write_debug(std::string_view output) const; |
| |
| /// OutputFormat getters. |
| Options::OutputFormat get_format() const; |
| bool print_rpc_message() const; |
| bool is_json_format() const; |
| bool is_legacy_format() const; |
| bool is_records_format() const; |
| bool is_pretty_format() const; |
| |
| protected: |
| void write_output_json(YAML::Node const &node) const; |
| Options _printOpt; |
| }; |
| |
| inline BasePrinter::Options::OutputFormat |
| BasePrinter::get_format() const |
| { |
| return _printOpt._format; |
| } |
| |
| inline bool |
| BasePrinter::print_rpc_message() const |
| { |
| return get_format() == Options::OutputFormat::RPC; |
| } |
| |
| inline bool |
| BasePrinter::is_json_format() const |
| { |
| return get_format() == Options::OutputFormat::JSON; |
| } |
| |
| inline bool |
| BasePrinter::is_legacy_format() const |
| { |
| return get_format() == Options::OutputFormat::LEGACY; |
| } |
| inline bool |
| BasePrinter::is_records_format() const |
| { |
| return get_format() == Options::OutputFormat::RECORDS; |
| } |
| inline bool |
| BasePrinter::is_pretty_format() const |
| { |
| return get_format() == Options::OutputFormat::PRETTY; |
| } |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class GenericPrinter : public BasePrinter |
| { |
| void |
| write_output(YAML::Node const &result) override |
| { |
| /* muted */ |
| } |
| |
| public: |
| GenericPrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class RecordPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| void write_output_legacy(shared::rpc::RecordLookUpResponse const &result); |
| void write_output_pretty(shared::rpc::RecordLookUpResponse const &result); |
| |
| public: |
| RecordPrinter(Options opt) : BasePrinter(opt) { _printAsRecords = is_records_format(); } |
| |
| protected: |
| bool _printAsRecords{false}; |
| }; |
| |
| class MetricRecordPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| |
| public: |
| MetricRecordPrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class DiffConfigPrinter : public RecordPrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| void write_output_pretty(YAML::Node const &result); |
| |
| public: |
| DiffConfigPrinter(BasePrinter::Options opt) : RecordPrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class ConfigReloadPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| void write_output_pretty(YAML::Node const &result); |
| |
| public: |
| ConfigReloadPrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class ConfigShowFileRegistryPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| void write_output_pretty(YAML::Node const &result); |
| |
| public: |
| using BasePrinter::BasePrinter; |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class ConfigSetPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| |
| public: |
| using BasePrinter::BasePrinter; |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class RecordDescribePrinter : public BasePrinter |
| { |
| void write_output_legacy(shared::rpc::RecordLookUpResponse const &result); |
| void write_output_pretty(shared::rpc::RecordLookUpResponse const &result); |
| void write_output(YAML::Node const &result) override; |
| |
| public: |
| RecordDescribePrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class GetHostStatusPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| |
| public: |
| GetHostStatusPrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class SetHostStatusPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| |
| public: |
| SetHostStatusPrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class CacheDiskStoragePrinter : public BasePrinter |
| { |
| void write_output_pretty(YAML::Node const &result); |
| void write_output(YAML::Node const &result) override; |
| |
| public: |
| CacheDiskStoragePrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class CacheDiskStorageOfflinePrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| void write_output_pretty(YAML::Node const &result); |
| |
| public: |
| CacheDiskStorageOfflinePrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |
| class RPCAPIPrinter : public BasePrinter |
| { |
| void write_output(YAML::Node const &result) override; |
| |
| public: |
| RPCAPIPrinter(BasePrinter::Options opt) : BasePrinter(opt) {} |
| }; |
| //------------------------------------------------------------------------------------------------------------------------------------ |