.. program:: jetstream api

####################
Console API Examples
####################

The console API is accessed by specifying the ``api`` subcommand with the :program:`jetstream` command.

Connecting To A Server
======================
Each invocation of an API command through the console automatically connects to the server when
executed, and disconnects on exit.

The :option:`--host` and :option:`--api-control-port` parameters are used to specify the JetStream server to which
the console API will be connected. These parameters are specified *after* the ``api`` subcommand,
but *before* the API command.

The :option:`--user` parameter is used to authenticate the user on the JetStream server to which
the console API will be connected. Password will be read from environment variable :envvar:`JETSTREAM_API_PASSWORD` if
set.  Otherwise an interactive password input prompt will be displayed.

Example:
    .. code-block:: bash

        jetstream api --host <host> --user <user> <command> [options]

.. tip::

    Default Host
        If you do not specify the :option:`--host` parameter, the default used is ``localhost``.
    Default Port
        If you do not specify the :option:`--api-control-port` parameter, the default used is ``8886``.

If the JetStream Server was setup to use non-default API port, you will have to specify it using the :option:`--api-control-port` option. For Example:

.. code-block:: shell-session

   # jetstream api --api-control-port=57110 getServerInfo
   {
    "allowRemoteControl": true,
    "apiControlPort": 57110,
    "apiVersion": 26,
    [...]
    "version": "1.7.999"
   }


Creating a Manifest
===================

The :meth:`~jetstream.sendinterface.SendInterface.createManifest` command will initialize a manifest that, when attached to a transfer, will send
the local file ``/local/home/readme.txt`` to a destination, saving it at the path ``/data/docs/readme.txt``. It returns a :ref:`structure-manifest`.

.. code-block:: shell-session

   # jetstream api --user user createManifest --fileMappings="/local/home/readme.txt:/data/docs/readme.txt"
   {
    "errorMessage": "",
    "manifestId": "3bc6f6c9b5a0aa221000000000000000",
    "owner": "user",
    "processing": true,
    "status": "pending",
    "totalFiles": null,
    "totalSize": null,
    "userData": {}
   }

.. tip::

    When running on Windows and both the source and destination paths include a drive letter, you can use ``::`` as the file separator in the ``fileMappings`` parameter.

Monitoring a Manifest
=====================

The :meth:`~jetstream.sendinterface.SendInterface.createManifest` command returns immediately, with a reference to a ``manifestId``. We can use :meth:`~jetstream.sendinterface.SendInterface.getManifest` to check on the manifest asynchronously, or :meth:`~jetstream.sendinterface.SendInterface.waitForManifest` to block until the server has finished processing the manifest. Simiar to ``createManifest``, both commands return a :ref:`structure-manifest`.


.. code-block:: shell-session

   # jetstream api --user user waitForManifest --manifestId=3bc6f6c9b5a0aa221000000000000000
   {
    "errorMessage": "",
    "manifestId": "3bc6f6c9b5a0aa221000000000000000",
    "owner": "user",
    "processing": false,
    "status": "complete",
    "totalFiles": 1,
    "totalSize": 100,
    "userData": {}
   }

On completion, the manifest will report its ``status`` as one of the following:

    * ``complete``: The manifest has been completed successfully.
    * ``error``: The manifest failed. The ``errorMessage`` field will contain a description of the error.

When a manifest has initialized successfully, its ``totalFiles`` and ``totalSize`` fields will
reflect the size of the manifest.

.. note::

   Creating a manifest does not begin sending its files. For this, you need to attach the manifest to a *transfer*, which is sent to a *destination*.

Creating a Destination
======================

Before you can start a file transfer, you must create a destination using the :meth:`~jetstream.sendinterface.SendInterface.createDestination`` command, which returns a :ref:`structure-destination`.

.. code-block:: shell-session

   # jetstream api createDestination --destinationAddress="localhost" --destinationPort=8886
   {
    "connectionId": "3bc6f6c9b5a0aa224000000000000000",
    "destinationAddress": "localhost",
    "destinationIP": "127.0.0.1",
    "destinationId": "3bc6f6c9b5a0aa223000000000000000",
    [...]
    "userData": {}
   }


Creating a Transfer
===================

We'll use the output from the ``createManifest`` and ``createDestiantion`` commands prepared above. For the transfer to start, we will need to authenticate with the remote server. For this example, we'll use a user ``datamover``, which is used for authentication at the remote server. Password for ``--userName`` can be passed in by setting by :envvar:`JETSTREAM_TRANSFER_PASSWORD` environment variable.  Otherwise an interactive password input prompt will be displayed.

The :meth:`~jetstream.sendinterface.SendInterface.createTransfer` command returns a :ref:`structure-transfer`:

.. code-block:: shell-session

   # jetstream api createTransfer --destinationId=3bc6f6c9b5a0aa223000000000000000 --manifestId=3bc6f6c9b5a0aa221000000000000000 --userName=datamover
   {
    "blockSize": 256,
    "blocksAcked": 0,
    "blocksRetransmitted": 0,
    "blocksSent": 0,
    "bytesRecv": 0,
    "bytesSent": 0,
    [...]
    "processing": true,
    "status": "pending",
    "transferId": "3bc6f6c9b5a0aa222000000000000000",
    "userData": {}
   }


Monitoring A Transfer
=====================

The :meth:`~jetstream.sendinterface.SendInterface.createTransfer` command returns immediately, with a reference to a ``transferId``. We can use the :meth:`~jetstream.sendinterface.SendInterface.getTransfer` function to check on the transfer asynchronously, or :meth:`~jetstream.sendinterface.SendInterface.waitForTransfer` to block until the server has finished transferring. Simiar to ``createTransfer``, both commands return :ref:`structure-transfer`.

.. code-block:: shell-session

   # jetstream api --user user waitForTransfer --transferId=3bc6f6c9b5a0aa222000000000000000
   {
    [...]
    "processing": false,
    "status": "complete",
    "transferId": "3bc6f6c9b5a0aa222000000000000000",
    "userData": {}
   }

On completion, the transfer will report its status as one of the following:

    * ``complete``: The transfer has been completed successfully.
    * ``suspended``: The transfer was suspended. Use ``resumeTransfer`` to resume transmitting.
    * ``error``: The transfer failed. The ``errorMessage`` field will contain a description of the error.

