CORDA-1764: Make blobinspector use picocli base class (#3940)

* Make blobinspector use picocli base class

* Updated Documentation

* Update and harmonise documentation

* Give the table a bit more padding to help with merge conflicts

* Correct capitalisation of short options

* Some grammar changes
This commit is contained in:
Anthony Keenan 2018-09-14 16:37:58 +01:00 committed by GitHub
parent 356bddb2d4
commit 99dd2c5936
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 176 additions and 105 deletions

View File

@ -90,3 +90,25 @@ Here's what a node-info file from the node's data directory may look like:
Notice the file is actually a serialised ``SignedNodeInfo`` object, which has a ``raw`` property of type ``SerializedBytes<NodeInfo>``.
This property is materialised into a ``NodeInfo`` and is output under the ``deserialized`` field.
Command-line options
~~~~~~~~~~~~~~~~~~~~
The blob inspector can be started with the following command-line options:
.. code-block:: shell
blob-inspector [-hvV] [--full-parties] [--install-shell-extensions] [--schema]
[--format=type] [--input-format=type]
[--logging-level=<loggingLevel>] [SOURCE]
* ``--format=type``: Output format. Possible values: [YAML, JSON]. Default: YAML.
* ``--input-format=type``: Input format. If the file can't be decoded with the given value it's auto-detected, so you should
never normally need to specify this. Possible values [BINARY, HEX, BASE64]. Default: BINARY.
* ``--full-parties``: Display the owningKey and certPath properties of Party and PartyAndReference objects respectively.
* ``--schema``: Print the blob's schema first.
* ``--verbose``, ``--log-to-console``, ``-v``: If set, prints logging to the console as well as to a file.
* ``--logging-level=<loggingLevel>``: Enable logging at this level and higher. Possible values: ERROR, WARN, INFO, DEBUG, TRACE. Default: INFO.
* ``--install-shell-extensions``: Install ``blob-inspector`` alias and auto completion for bash and zsh. See :doc:`cli-application-shell-extensions` for more info.
* ``--help``, ``-h``: Show this help message and exit.
* ``--version``, ``-V``: Print version information and exit.

View File

@ -0,0 +1,76 @@
Shell extensions for CLI Applications
=====================================
.. _installing-shell-extensions:
Installing shell extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Users of ``bash`` or ``zsh`` can install an alias and auto-completion for Corda applications that contain a command line interface. Run:
.. code-block:: shell
java -jar <name-of-JAR>.jar --install-shell-extensions
Then, either restart your shell, or for ``bash`` users run:
.. code-block:: shell
. ~/.bashrc
Or, for ``zsh`` run:
.. code-block:: shell
. ~/.zshrc
You will now be able to run the command line application from anywhere by running the following:
.. code-block:: shell
<alias> --<option>
For example, for the Corda node, install the shell extensions using
.. code-block:: shell
java -jar corda-<version>.jar --install-shell-extensions
And then run the node by running:
.. code-block:: shell
corda --<option>
Upgrading shell extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~
Once the shell extensions have been installed, you can upgrade them in one of two ways.
1) Overwrite the existing JAR with the newer version. The next time you run the application, it will automatically update
the completion file. Either restart the shell or see :ref:`above<installing-shell-extensions>` for instructions
on making the changes take effect immediately.
2) If you wish to use a new JAR from a different directory, navigate to that directory and run:
.. code-block:: shell
java -jar <name-of-JAR>
Which will update the alias to point to the new location, and update command line completion functionality. Either
restart the shell or see :ref:`above<installing-shell-extensions>` for instructions on making the changes take effect immediately.
List of existing CLI applications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+----------------------------------------------------------------+--------------------------------------------------------------+--------------------------------+
| Description | JAR name | Alias |
+----------------------------------------------------------------+--------------------------------------------------------------+--------------------------------+
| :ref:`Corda node<starting-an-individual-corda-node>` | ``corda-<version>.jar`` | ``corda --<option>`` |
+----------------------------------------------------------------+--------------------------------------------------------------+--------------------------------+
| :doc:`Network bootstrapper<network-bootstrapper>` | ``corda-tools-network-bootstrapper-<version>.jar`` | ``bootstrapper --<option>`` |
+----------------------------------------------------------------+--------------------------------------------------------------+--------------------------------+
| :ref:`Standalone shell<standalone-shell>` | ``corda-tools-shell-cli-<version>.jar`` | ``corda-shell --<option>`` |
+----------------------------------------------------------------+--------------------------------------------------------------+--------------------------------+
| :doc:`Blob inspector<blob-inspector>` | ``corda-tools-blob-inspector-<version>.jar`` | ``blob-inspector --<option>`` |
+----------------------------------------------------------------+--------------------------------------------------------------+--------------------------------+

View File

@ -53,6 +53,7 @@ We look forward to seeing what you can do with Corda!
aws-vm.rst
loadtesting.rst
building-container-images.rst
cli-application-shell-extensions.rst
.. Documentation is not included in the pdf unless it is included in a toctree somewhere

View File

@ -245,3 +245,22 @@ To give the following:
.. note:: The whitelist can only ever be appended to. Once added a contract implementation can never be removed.
Command-line options
--------------------
The network bootstrapper can be started with the following command-line options:
.. code-block:: shell
bootstrapper [-hvV] [--install-shell-extensions] [--no-copy] [--dir=<dir>]
[--logging-level=<loggingLevel>]
* ``--dir=<dir>``: Root directory containing the node configuration files and CorDapp JARs that will form the test network.
It may also contain existing node directories. Defaults to the current directory.
* ``--no-copy``: Don't copy the CorDapp JARs into the nodes' "cordapps" directories.
* ``--verbose``, ``--log-to-console``, ``-v``: If set, prints logging to the console as well as to a file.
* ``--logging-level=<loggingLevel>``: Enable logging at this level and higher. Possible values: ERROR, WARN, INFO, DEBUG, TRACE. Default: INFO.
* ``--install-shell-extensions``: Install ``bootstrapper`` alias and auto completion for bash and zsh. See :doc:`cli-application-shell-extensions` for more info.
* ``--help``, ``-h``: Show this help message and exit.
* ``--version``, ``-V``: Print version information and exit.

View File

@ -53,69 +53,21 @@ The node can optionally be started with the following command-line options:
* ``--clear-network-map-cache``, ``-c``: Clears local copy of network map, on node startup it will be restored from server or file system.
* ``--config-file``, ``-f``: The path to the config file. Defaults to ``node.conf``.
* ``--dev-mode``, ``-d``: Runs the node in developer mode. Unsafe in production. Defaults to true on MacOS and desktop versions of Windows. False otherwise.
* ``--help``, ``-h``: Displays the help message and exits.
* ``--initial-registration``: Start initial node registration with Corda network to obtain certificate from the permissioning
server.
* ``--install-shell-extensions``: Installs an alias and auto-completion for users of ``bash`` or ``zsh``. See below for more information.
* ``--just-generate-node-info``: Perform the node start-up task necessary to generate its nodeInfo, save it to disk, then
* ``--initial-registration``: Start initial node registration with the compatibility zone to obtain a certificate from the Doorman.
* ``--just-generate-node-info``: Perform the node start-up task necessary to generate its nodeInfo, save it to disk, then
quit.
* ``--just-generate-rpc-ssl-settings``: Generate the ssl keystore and truststore for a secure RPC connection.
* ``--log-to-console``, ``--verbose``, ``-v``: If set, prints logging to the console as well as to a file.
* ``--logging-level <[ERROR,WARN,INFO,DEBUG,TRACE]>``: Enable logging at this level and higher. Defaults to INFO.
* ``--network-root-truststore``, ``-t``: Network root trust store obtained from network operator.
* ``--network-root-truststore-password``, ``-p``: Network root trust store password obtained from network operator.
* ``--no-local-shell``, ``-n``: Do not start the embedded shell locally.
* ``--on-unknown-config-keys <[FAIL,WARN,INFO]>``: How to behave on unknown node configuration. Defaults to FAIL.
* ``--sshd``: Enables SSH server for node administration.
* ``--sshd-port``: Sets the port for the SSH server. If not supplied and SSH server is enabled, the port defaults to 2222.
* ``--version``, ``-V``: Prints the version and exits.
.. _installing-shell-extensions:
Installing shell extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Users of ``bash`` or ``zsh`` can install an alias and command line completion for Corda. Run:
.. code-block:: shell
java -jar corda.jar --install-shell-extensions
Then, either restart your shell, or for ``bash`` users run:
.. code-block:: shell
. ~/.bashrc
Or, for ``zsh`` run:
.. code-block:: shell
. ~/.zshrc
You will now be able to run a Corda node from anywhere by running the following:
.. code-block:: shell
corda --<option>
Upgrading shell extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~
Once the shell extensions have been installed, you can upgrade them in one of two ways.
1) Overwrite the existing ``corda.jar`` with the newer version. The next time you run Corda, it will automatically update
the completion file. Either restart the shell or see :ref:`above<installing-shell-extensions>` for instructions
on making the changes take effect immediately.
2) If you wish to use a new ``corda.jar`` from a different directory, navigate to that directory and run:
.. code-block:: shell
java -jar corda.jar
Which will update the ``corda`` alias to point to the new location, and update command line completion functionality. Either
restart the shell or see :ref:`above<installing-shell-extensions>` for instructions on making the changes take effect immediately.
* ``--verbose``, ``--log-to-console``, ``-v``: If set, prints logging to the console as well as to a file.
* ``--logging-level=<loggingLevel>``: Enable logging at this level and higher. Possible values: ERROR, WARN, INFO, DEBUG, TRACE. Default: INFO.
* ``--install-shell-extensions``: Install ``corda`` alias and auto completion for bash and zsh. See :doc:`cli-application-shell-extensions` for more info.
* ``--help``, ``-h``: Show this help message and exit.
* ``--version``, ``-V``: Print version information and exit.
.. _enabling-remote-debugging:

View File

@ -92,6 +92,8 @@ Windows
Windows does not provide a built-in SSH tool. An alternative such as PuTTY should be used.
.. _standalone-shell:
The standalone shell
--------------------
The standalone shell is a standalone application interacting with a Corda node via RPC calls.
@ -117,26 +119,34 @@ Windows
.. code:: bash
java -jar corda-tools-shell-cli-VERSION_NUMBER.jar [--config-file PATH | --cordpass-directory PATH --commands-directory PATH --host HOST --port PORT
--user USER --password PASSWORD --sshd-port PORT --sshd-hostkey-directory PATH --keystore-password PASSWORD
--keystore-file FILE --truststore-password PASSWORD --truststore-file FILE | --help]
corda-shell [-hvV] [--install-shell-extensions]
[--logging-level=<loggingLevel>] [--password=<password>]
[--sshd-hostkey-directory=<sshdHostKeyDirectory>]
[--sshd-port=<sshdPort>] [--truststore-file=<trustStoreFile>]
[--truststore-password=<trustStorePassword>]
[--truststore-type=<trustStoreType>] [--user=<user>] [-a=<host>]
[-c=<cordappDirectory>] [-f=<configFile>] [-o=<commandsDirectory>]
[-p=<port>]
Where:
* ``config-file`` is the path to config file, used instead of providing the rest of command line options
* ``cordpass-directory`` is the directory containing Cordapps jars, Cordapps are require when starting flows
* ``commands-directory`` is the directory with additional CRaSH shell commands
* ``host`` is the Corda node's host
* ``port`` is the Corda node's port, specified in the ``node.conf`` file
* ``user`` is the RPC username, if not provided it will be requested at startup
* ``password`` is the RPC user password, if not provided it will be requested at startup
* ``sshd-port`` instructs the standalone shell app to start SSH server on the given port, optional
* ``sshd-hostkey-directory`` is the directory containing hostkey.pem file for SSH server
* ``keystore-password`` the password to unlock the KeyStore file containing the standalone shell certificate and private key, optional, unencrypted RPC connection without SSL will be used if the option is not provided
* ``keystore-file`` is the path to the KeyStore file
* ``truststore-password`` the password to unlock the TrustStore file containing the Corda node certificate, optional, unencrypted RPC connection without SSL will be used if the option is not provided
* ``truststore-file`` is the path to the TrustStore file
* ``help`` prints Shell help
* ``--config-file=<configFile>``, ``--f`` The path to the shell configuration file, used instead of providing the rest of the command line options.
* ``--cordapp-directory=<cordappDirectory>``, ``-c`` The path to the directory containing CorDapp jars, CorDapps are required when starting flows.
* ``--commands-directory=<commandsDirectory>``, ``-o`` The path to the directory containing additional CRaSH shell commands.
* ``--host``, ``-a``: The host address of the Corda node.
* ``--port``, ``-p``: The RPC port of the Corda node.
* ``--user=<user>``: The RPC user name.
* ``--password=<password>`` The RPC user password. If not provided it will be prompted for on startup.
* ``--sshd-port=<sshdPort>`` Enables SSH server for shell.
* ``--sshd-hostkey-directory=<sshHostKeyDirectory``: The directory containing the hostkey.pem file for the SSH server.
* ``--truststore-password=<trustStorePassword>``: The password to unlock the TrustStore file.
* ``--truststore-file=<trustStoreFile>``: The path to the TrustStore file.
* ``--truststore-type=<trustStoreType>``: The type of the TrustStore (e.g. JKS).
* ``--verbose``, ``--log-to-console``, ``-v``: If set, prints logging to the console as well as to a file.
* ``--logging-level=<loggingLevel>``: Enable logging at this level and higher. Possible values: ERROR, WARN, INFO, DEBUG, TRACE. Default: INFO.
* ``--install-shell-extensions``: Install ``corda-shell`` alias and auto completion for bash and zsh. See :doc:`cli-application-shell-extensions` for more info.
* ``--help``, ``-h``: Show this help message and exit.
* ``--version``, ``-V``: Print version information and exit.
The format of ``config-file``:

View File

@ -5,7 +5,7 @@ apply plugin: 'com.jfrog.artifactory'
dependencies {
compile project(':client:jackson')
compile "info.picocli:picocli:$picocli_version"
compile project(':tools:cliutils')
compile "org.slf4j:jul-to-slf4j:$slf4j_version"
compile "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
compile "com.jcabi:jcabi-manifests:$jcabi_manifests_version"
@ -23,10 +23,9 @@ jar {
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
archiveName = "blob-inspector-${corda_release_version}.jar"
baseName = "blob-inspector"
manifest {
attributes(
'Automatic-Module-Name': 'net.corda.blobinspector',
'Main-Class': 'net.corda.blobinspector.BlobInspectorKt'
)
}

View File

@ -4,6 +4,9 @@ import com.fasterxml.jackson.core.JsonFactory
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.jcabi.manifests.Manifests
import net.corda.client.jackson.JacksonSupport
import net.corda.cliutils.CordaCliWrapper
import net.corda.cliutils.ExitCodes
import net.corda.cliutils.start
import net.corda.core.internal.isRegularFile
import net.corda.core.internal.rootMessage
import net.corda.core.serialization.SerializationContext
@ -21,39 +24,23 @@ import net.corda.serialization.internal.SerializationFactoryImpl
import net.corda.serialization.internal.amqp.AbstractAMQPSerializationScheme
import net.corda.serialization.internal.amqp.DeserializationInput
import net.corda.serialization.internal.amqp.amqpMagic
import org.slf4j.event.Level
import picocli.CommandLine
import picocli.CommandLine.*
import java.io.PrintStream
import java.net.MalformedURLException
import java.net.URL
import java.nio.file.Paths
import java.util.*
import kotlin.system.exitProcess
fun main(args: Array<String>) {
val main = BlobInspector()
try {
CommandLine.run(main, *args)
} catch (e: ExecutionException) {
val throwable = e.cause ?: e
if (main.verbose) {
throwable.printStackTrace()
} else {
System.err.println("*ERROR*: ${throwable.rootMessage}. Use --verbose for more details")
}
exitProcess(1)
}
BlobInspector().start(args)
}
@Command(
name = "blob-inspector",
versionProvider = CordaVersionProvider::class,
mixinStandardHelpOptions = true, // add --help and --version options,
showDefaultValues = true,
description = ["Convert AMQP serialised binary blobs to text"]
)
class BlobInspector : Runnable {
@Parameters(index = "0", paramLabel = "SOURCE", description = ["URL or file path to the blob"], converter = [SourceConverter::class])
var source: URL? = null
class BlobInspector : CordaCliWrapper("blob-inspector", "Convert AMQP serialised binary blobs to text") {
@Parameters(index = "*..0", paramLabel = "SOURCE", description = ["URL or file path to the blob"], converter = [SourceConverter::class])
var source: MutableList<URL> = mutableListOf()
@Option(names = ["--format"], paramLabel = "type", description = ["Output format. Possible values: [YAML, JSON]"])
private var formatType: OutputFormatType = OutputFormatType.YAML
@ -68,17 +55,19 @@ class BlobInspector : Runnable {
@Option(names = ["--schema"], description = ["Print the blob's schema first"])
private var schema: Boolean = false
@Option(names = ["--verbose"], description = ["Enable verbose output"])
var verbose: Boolean = false
override fun runProgram() = run(System.out)
override fun run() = run(System.out)
fun run(out: PrintStream) {
override fun initLogging() {
if (verbose) {
System.setProperty("logLevel", "trace")
loggingLevel = Level.TRACE
}
val loggingLevel = loggingLevel.name.toLowerCase(Locale.ENGLISH)
System.setProperty("logLevel", loggingLevel) // This property is referenced from the XML config file.
}
val inputBytes = source!!.readBytes()
fun run(out: PrintStream): Int {
require(source.count() == 1) { "You must specify URL or file path to the blob" }
val inputBytes = source.first().readBytes()
val bytes = parseToBinaryRelaxed(inputFormatType, inputBytes)
?: throw IllegalArgumentException("Error: this input does not appear to be encoded in Corda's AMQP extended format, sorry.")
@ -102,6 +91,9 @@ class BlobInspector : Runnable {
val deserialized = bytes.deserialize<Any>(context = SerializationDefaults.STORAGE_CONTEXT)
out.println(deserialized.javaClass.name)
mapper.writeValue(out, deserialized)
return ExitCodes.SUCCESS
} catch(e: Exception) {
return ExitCodes.FAILURE
} finally {
_contextSerializationEnv.set(null)
}

View File

@ -53,7 +53,7 @@ class BlobInspectorTest {
}
private fun run(resourceName: String): String {
blobInspector.source = javaClass.getResource(resourceName)
blobInspector.source = mutableListOf(javaClass.getResource(resourceName))
val writer = StringWriter()
blobInspector.run(PrintStream(WriterOutputStream(writer, UTF_8)))
val output = writer.toString()