Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions doc/appendices/command-line/traffic_ctl_jsonrpc.en.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ Options
it's not required to always implement a pretty output
``json`` It will show the response message formatted to `JSON`_. This is ideal if you want to redirect the stdout to a different source.
It will only stream the json response, no other messages.
``data:`` This is an addon to the default format style, data can be: ``{req|resp|all}`` which will make :program:`traffic_ctl`
to print in json format the request or response or both.
``rpc`` Show the JSONRPC request and response + the default output.
=================== ========================================================================

In case of a record request(config) ``--records`` overrides this flag.
Expand All @@ -96,19 +95,10 @@ Options

.. code-block::

traffic_ctl config get variable --format data:req
--> {request}

.. code-block::

$ traffic_ctl config get variable --format data:resp
<-- {response}

.. code-block::

$ traffic_ctl config get variable --format data:all
$ traffic_ctl config get variable --format rpc
--> {request}
<-- {response}
variable 1234

.. code-block::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,9 @@ please check the ``CustomJSONRPCResponse`` tester for more information.
AddJsonRPCClientRequest
~~~~~~~~~~~~~~~~~~~~~~~

This function will generate a json response as an output, internally it ses :program:`traffic_ctl file --format json` as client.
The output can be used and compared with a gold file. This also provides schema validation for the entire JSONRPC protocol as well as
the ``param`` field against a specific schema file. You can specify ``schema_file_name`` with a valid json schema file to validate
This function will generate a json response as an output, internally it uses :program:`traffic_ctl rpc file --format json` as client.
The output can be used and compared with a gold file. This also provides an optional schema validation for the entire JSONRPC protocol
as well as the ``param`` field against a specific schema file. You can specify ``schema_file_name`` with a valid json schema file to validate
the entire JSONRPC 2.0 request(except the content of the ``params`` field). You can also set ``params_field_schema_file_name`` with a
valid json schema file to validate only the ``params`` field.

Expand Down
26 changes: 12 additions & 14 deletions src/traffic_ctl_jsonrpc/CtrlCommands.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,23 @@ namespace
/// We use yamlcpp as codec implementation.
using Codec = yamlcpp_json_emitter;

const std::unordered_map<std::string_view, BasePrinter::Options::Format> _Fmt_str_to_enum = {
{"pretty", BasePrinter::Options::Format::PRETTY}, {"legacy", BasePrinter::Options::Format::LEGACY},
{"json", BasePrinter::Options::Format::JSON}, {"req", BasePrinter::Options::Format::DATA_REQ},
{"resp", BasePrinter::Options::Format::DATA_RESP}, {"all", BasePrinter::Options::Format::DATA_ALL}};
const std::unordered_map<std::string_view, BasePrinter::Options::OutputFormat> _Fmt_str_to_enum = {
{"pretty", BasePrinter::Options::OutputFormat::PRETTY},
{"legacy", BasePrinter::Options::OutputFormat::LEGACY},
{"json", BasePrinter::Options::OutputFormat::JSON},
{"rpc", BasePrinter::Options::OutputFormat::RPC}};

BasePrinter::Options::Format
BasePrinter::Options::OutputFormat
parse_format(ts::Arguments &args)
{
if (args.get("records")) {
return BasePrinter::Options::Format::RECORDS;
return BasePrinter::Options::OutputFormat::RECORDS;
}

BasePrinter::Options::Format val{BasePrinter::Options::Format::LEGACY};
BasePrinter::Options::OutputFormat val{BasePrinter::Options::OutputFormat::LEGACY};

if (auto data = args.get("format"); data) {
ts::TextView fmt{data.value()};
if ("data" == fmt.prefix(':')) {
fmt.take_prefix_at(':');
}
if (auto search = _Fmt_str_to_enum.find(fmt); search != std::end(_Fmt_str_to_enum)) {
val = search->second;
}
Expand Down Expand Up @@ -76,14 +74,14 @@ CtrlCommand::execute()
std::string
CtrlCommand::invoke_rpc(std::string const &request)
{
if (_printer->print_req_msg()) {
if (_printer->print_rpc_message()) {
std::string text;
ts::bwprint(text, "--> {}", request);
_printer->write_debug(std::string_view{text});
}
if (auto resp = _rpcClient.invoke(request); !resp.empty()) {
// all good.
if (_printer->print_resp_msg()) {
if (_printer->print_rpc_message()) {
std::string text;
ts::bwprint(text, "<-- {}", resp);
_printer->write_debug(std::string_view{text});
Expand Down Expand Up @@ -381,9 +379,9 @@ DirectRPCCommand::DirectRPCCommand(ts::Arguments args) : CtrlCommand(args)
_invoked_func = [&]() { read_from_input(); };
} else if (_arguments.get("invoke")) {
_invoked_func = [&]() { invoke_method(); };
if (printOpts._format == BasePrinter::Options::Format::LEGACY) {
if (printOpts._format == BasePrinter::Options::OutputFormat::LEGACY) {
// overwrite this and let it drop json instead.
printOpts._format = BasePrinter::Options::Format::DATA_ALL;
printOpts._format = BasePrinter::Options::OutputFormat::RPC;
}
}

Expand Down
37 changes: 14 additions & 23 deletions src/traffic_ctl_jsonrpc/CtrlPrinters.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ 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 Format {
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.
DATA_REQ, // Print json request + default format
DATA_RESP, // Print json response + default format
DATA_ALL // Print json request and response + default format
RPC // Print JSONRPC request and response + default output.
};
Options() = default;
Options(Format fmt) : _format(fmt) {}
Format _format{Format::LEGACY}; //!< selected(passed) format.
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.
Expand Down Expand Up @@ -81,10 +79,9 @@ class BasePrinter
virtual void write_output(std::string_view output) const;
virtual void write_debug(std::string_view output) const;

/// Format getters.
Options::Format get_format() const;
bool print_req_msg() const;
bool print_resp_msg() 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;
Expand All @@ -95,44 +92,38 @@ class BasePrinter
Options _printOpt;
};

inline BasePrinter::Options::Format
inline BasePrinter::Options::OutputFormat
BasePrinter::get_format() const
{
return _printOpt._format;
}

inline bool
BasePrinter::print_req_msg() const
BasePrinter::print_rpc_message() const
{
return get_format() == Options::Format::DATA_ALL || get_format() == Options::Format::DATA_REQ;
}

inline bool
BasePrinter::print_resp_msg() const
{
return get_format() == Options::Format::DATA_ALL || get_format() == Options::Format::DATA_RESP;
return get_format() == Options::OutputFormat::RPC;
}

inline bool
BasePrinter::is_json_format() const
{
return get_format() == Options::Format::JSON;
return get_format() == Options::OutputFormat::JSON;
}

inline bool
BasePrinter::is_legacy_format() const
{
return get_format() == Options::Format::LEGACY;
return get_format() == Options::OutputFormat::LEGACY;
}
inline bool
BasePrinter::is_records_format() const
{
return get_format() == Options::Format::RECORDS;
return get_format() == Options::OutputFormat::RECORDS;
}
inline bool
BasePrinter::is_pretty_format() const
{
return get_format() == Options::Format::PRETTY;
return get_format() == Options::OutputFormat::PRETTY;
}
//------------------------------------------------------------------------------------------------------------------------------------
class GenericPrinter : public BasePrinter
Expand Down
3 changes: 1 addition & 2 deletions src/traffic_ctl_jsonrpc/traffic_ctl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ main(int argc, const char **argv)
.add_option("--version", "-V", "Print version string")
.add_option("--help", "-h", "Print usage information")
.add_option("--run-root", "", "using TS_RUNROOT as sandbox", "TS_RUNROOT", 1)
.add_option("--format", "-f", "Use a specific output format {legacy|pretty|json|data:{req|resp|all}}", "", 1, "legacy",
"format");
.add_option("--format", "-f", "Use a specific output format {legacy|pretty|json|rpc}", "", 1, "legacy", "format");

auto &config_command = parser.add_command("config", "Manipulate configuration records").require_commands();
auto &metric_command = parser.add_command("metric", "Manipulate performance metrics").require_commands();
Expand Down