blob: c641f5b6f6f565732a7b8140125729f3a92df1f2 [file] [log] [blame]
/** @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) {}
};
//------------------------------------------------------------------------------------------------------------------------------------