You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by dm...@apache.org on 2022/03/01 11:42:20 UTC

[trafficserver] branch 10-Dev updated: traffic_ctl - Add rpc invoke option. (#8695)

This is an automated email from the ASF dual-hosted git repository.

dmeden pushed a commit to branch 10-Dev
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/10-Dev by this push:
     new 20d2241  traffic_ctl - Add rpc invoke option. (#8695)
20d2241 is described below

commit 20d22411be7c1dfff445770b944d892b7a0e89ee
Author: Damian Meden <da...@gmail.com>
AuthorDate: Tue Mar 1 11:42:09 2022 +0000

    traffic_ctl - Add rpc invoke option. (#8695)
    
    Add Input option to invoke a rpc function by specifying the method name and the parameters directly
    from the command line.
---
 .../command-line/traffic_ctl_jsonrpc.en.rst        | 36 ++++++++++++++++++++++
 .../jsonrpc/jsonrpc-architecture.en.rst            |  1 -
 include/shared/rpc/RPCRequests.h                   |  4 +--
 src/traffic_ctl_jsonrpc/CtrlCommands.cc            | 25 +++++++++++++++
 src/traffic_ctl_jsonrpc/CtrlCommands.h             |  1 +
 src/traffic_ctl_jsonrpc/jsonrpc/CtrlRPCRequests.h  | 11 -------
 src/traffic_ctl_jsonrpc/traffic_ctl.cc             |  6 +++-
 7 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/doc/appendices/command-line/traffic_ctl_jsonrpc.en.rst b/doc/appendices/command-line/traffic_ctl_jsonrpc.en.rst
index 6b165b2..ebb91cc 100644
--- a/doc/appendices/command-line/traffic_ctl_jsonrpc.en.rst
+++ b/doc/appendices/command-line/traffic_ctl_jsonrpc.en.rst
@@ -538,6 +538,42 @@ but rather to the rpc endpoint, so you can directly send requests and receive re
          }
       }
 
+
+.. option:: invoke
+
+   Invoke a remote call by using the method name as parameter. This could be a handy option if you are developing a new handler or you
+   just don't want to expose the method in :program:`traffic_ctl`, for instance when implementing a custom handler inside a proprietary plugin.
+
+   .. option:: --params, -p
+
+      Parameters to be passed in the request, YAML or JSON format are accepted. If JSON is passed as param it should not
+      be mixed with YAML. It's important that you follow the :ref:`jsonrpc-protocol` specs. If the passed param does not
+      follows the specs the server will reject the request.
+
+.. _rpc_invoke_example_1:
+
+   Example 1:
+
+   Call a jsonrpc method with no parameter.
+
+   .. code-block::
+
+      $ traffic_ctl rpc invoke some_jsonrpc_handler
+      --> {"id": "0dbab88d-b78f-4ebf-8aa3-f100031711a5", "jsonrpc": "2.0", "method": "some_jsonrpc_handler"}
+      <-- { response }
+
+.. _rpc_invoke_example_2:
+
+   Example 2:
+
+   Call a jsonrpc method with parameters.
+
+   .. code-block::
+
+      $ traffic_ctl rpc invoke reload_files_from_folder --params 'filenames: ["file1", "file2"]' 'folder: "/path/to/folder"'
+      --> {"id": "9ac68652-5133-4d5f-8260-421baca4c67f", "jsonrpc": "2.0", "method": "reload_files_from_folder", "params": {"filenames": ["file1", "file2"], "folder": "/path/to/folder"}}
+      <-- { response }
+
 Examples
 ========
 
diff --git a/doc/developer-guide/jsonrpc/jsonrpc-architecture.en.rst b/doc/developer-guide/jsonrpc/jsonrpc-architecture.en.rst
index 511e4e9..4025cbd 100644
--- a/doc/developer-guide/jsonrpc/jsonrpc-architecture.en.rst
+++ b/doc/developer-guide/jsonrpc/jsonrpc-architecture.en.rst
@@ -132,7 +132,6 @@ Please find the `jsonrpc 2.0 request` schema for reference ( `mgmt2/rpc/schema/j
 * Optional parameters:
 
 
-
    * ``params``:
 
       A Structured value that holds the parameter values to be used during the invocation of the method. This member
diff --git a/include/shared/rpc/RPCRequests.h b/include/shared/rpc/RPCRequests.h
index b12c666..5ab5a7c 100644
--- a/include/shared/rpc/RPCRequests.h
+++ b/include/shared/rpc/RPCRequests.h
@@ -42,7 +42,7 @@ struct JSONRPCRequest {
   virtual std::string
   get_method() const
   {
-    return "method";
+    return this->method;
   }
 };
 
@@ -225,4 +225,4 @@ operator<<(std::ostream &os, const JSONRPCError &err)
 
   return os;
 }
-} // namespace shared::rpc
\ No newline at end of file
+} // namespace shared::rpc
diff --git a/src/traffic_ctl_jsonrpc/CtrlCommands.cc b/src/traffic_ctl_jsonrpc/CtrlCommands.cc
index a71af91..c64ff06 100644
--- a/src/traffic_ctl_jsonrpc/CtrlCommands.cc
+++ b/src/traffic_ctl_jsonrpc/CtrlCommands.cc
@@ -379,6 +379,12 @@ DirectRPCCommand::DirectRPCCommand(ts::Arguments args) : CtrlCommand(args)
     _invoked_func = [&]() { from_file_request(); };
   } else if (_arguments.get("input")) {
     _invoked_func = [&]() { read_from_input(); };
+  } else if (_arguments.get("invoke")) {
+    _invoked_func = [&]() { invoke_method(); };
+    if (printOpts._format == BasePrinter::Options::Format::LEGACY) {
+      // overwrite this and let it drop json instead.
+      printOpts._format = BasePrinter::Options::Format::DATA_ALL;
+    }
   }
 
   _printer = std::make_unique<GenericPrinter>(printOpts);
@@ -458,6 +464,25 @@ DirectRPCCommand::read_from_input()
   }
 }
 
+void
+DirectRPCCommand::invoke_method()
+{
+  shared::rpc::ClientRequest request;
+  if (auto method = _arguments.get("invoke"); method) {
+    request.method = method.value();
+    // We build up the parameter content if passed.
+    if (auto params = _arguments.get("params"); params) {
+      std::ostringstream ss;
+      for (auto &&param : _arguments.get("params")) {
+        ss << param;
+        ss << '\n';
+      }
+      request.params = YAML::Load(ss.str()); // let if fail if this is bad.
+    }
+    _printer->write_output(invoke_rpc(request));
+  }
+}
+
 //------------------------------------------------------------------------------------------------------------------------------------
 ServerCommand::ServerCommand(ts::Arguments args) : CtrlCommand(args)
 {
diff --git a/src/traffic_ctl_jsonrpc/CtrlCommands.h b/src/traffic_ctl_jsonrpc/CtrlCommands.h
index 6144ded..5c6a7ce 100644
--- a/src/traffic_ctl_jsonrpc/CtrlCommands.h
+++ b/src/traffic_ctl_jsonrpc/CtrlCommands.h
@@ -163,6 +163,7 @@ private:
   void from_file_request();
   void get_rpc_api();
   void read_from_input();
+  void invoke_method();
   /// run a YAML validation on the input.
   bool validate_input(std::string const &in) const;
 };
diff --git a/src/traffic_ctl_jsonrpc/jsonrpc/CtrlRPCRequests.h b/src/traffic_ctl_jsonrpc/jsonrpc/CtrlRPCRequests.h
index c3d9740..b4466ab 100644
--- a/src/traffic_ctl_jsonrpc/jsonrpc/CtrlRPCRequests.h
+++ b/src/traffic_ctl_jsonrpc/jsonrpc/CtrlRPCRequests.h
@@ -221,17 +221,6 @@ struct ShowRegisterHandlersRequest : shared::rpc::ClientRequest {
   }
 };
 //------------------------------------------------------------------------------------------------------------------------------------
-// We expect the method to be passed, this request is used to create dynamic requests by using (traffic_ctl rpc invoke "func_name")
-struct CustomizableRequest : shared::rpc::ClientRequest {
-  using super = shared::rpc::ClientRequest;
-  CustomizableRequest(std::string const &methodName) { super::method = methodName; }
-  std::string
-  get_method() const
-  {
-    return super::method;
-  }
-};
-//------------------------------------------------------------------------------------------------------------------------------------
 ///
 /// @brief Config status request mapping class.
 ///
diff --git a/src/traffic_ctl_jsonrpc/traffic_ctl.cc b/src/traffic_ctl_jsonrpc/traffic_ctl.cc
index 7d7bd4b..48a017f 100644
--- a/src/traffic_ctl_jsonrpc/traffic_ctl.cc
+++ b/src/traffic_ctl_jsonrpc/traffic_ctl.cc
@@ -160,7 +160,11 @@ main(int argc, const char **argv)
                 "No json/yaml parse validation will take place, the raw content will be directly send to the server.", "", 0, "",
                 "raw")
     .add_example_usage("traffic_ctl rpc input ");
-
+  direct_rpc_command
+    .add_command("invoke", "Call a method by using the method name as input parameter", "", MORE_THAN_ONE_ARG_N,
+                 [&]() { command->execute(); })
+    .add_option("--params", "-p", "Parameters to be passed in the request, YAML or JSON format", "", MORE_THAN_ONE_ARG_N, "", "")
+    .add_example_usage("traffic_ctl rpc invoke foo_bar -p \"numbers: [1, 2, 3]\"");
   try {
     auto args = parser.parse(argv);
     argparser_runroot_handler(args.get("run-root").value(), argv[0]);