zephyr/samples/modules/thrift/hello
..
client
server
README.rst
hello.thrift
native-cert.pem
native-key.pem
overlay-tls.conf
qemu-cert.pem
qemu-key.pem
thrift-layers.png

README.rst

.. _thrift-hello-sample:

Thrift sample
#############

.. figure:: thrift-layers.png
   :align: center
   :alt: Thrift Layers

What is Thrift?
***************

`Apache Thrift`_ is an `IDL`_ specification, `RPC`_ framework, and
`code generator`_. It works across all major operating systems, supports over
27 programming languages, 7 protocols, and 6 low-level transports. Thrift was
originally developed at `Facebook in 2006`_ and then shared with the
`Apache Software Foundation`_. Thrift supports a rich set of types and data
structures, and abstracts away transport and protocol details, which lets
developers focus on application logic.

.. _Apache Thrift:
    https://github.com/apache/thrift

.. _IDL:
    https://en.wikipedia.org/wiki/Interface_description_language

.. _RPC:
    https://en.wikipedia.org/wiki/Remote_procedure_call

.. _code generator:
    https://en.wikipedia.org/wiki/Automatic_programming

.. _Facebook in 2006:
    https://thrift.apache.org/static/files/thrift-20070401.pdf

.. _Apache Software Foundation:
    https://www.apache.org

Overview
********

This sample application includes a client and server implementing the RPC
interface described in :zephyr_file:`samples/modules/thrift/hello/hello.thrift`.
The purpose of this example is to demonstrate how components at different
layers in thrift can be combined to build an application with desired features.


Requirements
************

- QEMU Networking (described in :ref:`networking_with_qemu`)
- Thrift dependencies installed for your host OS e.g. in Ubuntu

.. code-block:: console
   :caption: Install additional dependencies in Ubuntu

   sudo apt install -y libboost-all-dev thrift-compiler libthrift-dev

Building and Running
********************

This application can be run on a Linux host, with either the server or the
client in the QEMU environment, and the peer is built and run natively on
the host.

Building the Native Client and Server
=====================================

.. code-block:: console

   $ make -j -C samples/modules/thrift/hello/client/
   $ make -j -C samples/modules/thrift/hello/server/

Under ``client/``, 3 executables will be generated, and components
used in each layer of them are listed below:

+----------------------+------------+--------------------+------------------+
| hello_client         | TSocket    | TBufferedTransport | TBinaryProtocol  |
+----------------------+------------+--------------------+------------------+
| hello_client_compact | TSocket    | TBufferedTransport | TCompactProtocol |
+----------------------+------------+--------------------+------------------+
| hello_client_ssl     | TSSLSocket | TBufferedTransport | TBinaryProtocol  |
+----------------------+------------+--------------------+------------------+

The same applies for the server. Only the client and the server with the
same set of stacks can communicate.

Additionally, there is a ``hello_client.py`` Python script that can be used
interchangeably with the ``hello_client`` C++ application to illustrate the
cross-language capabilities of Thrift.

+----------------------+------------+--------------------+------------------+
| hello_client.py      | TSocket    | TBufferedTransport | TBinaryProtocol  |
+----------------------+------------+--------------------+------------------+

Running the Zephyr Server in QEMU
=================================

Build the Zephyr version of the ``hello/server`` sample application like this:

.. zephyr-app-commands::
   :zephyr-app: samples/modules/thrift/hello/server
   :board: board_name
   :goals: build
   :compact:

To enable advanced features, extra arguments should be passed accordingly:

- TCompactProtocol: ``-DCONFIG_THRIFT_COMPACT_PROTOCOL=y``
- TSSLSocket: ``-DCONF_FILE="prj.conf ../overlay-tls.conf"``

For example, to build for ``qemu_x86_64`` with TSSLSocket support:

.. zephyr-app-commands::
   :zephyr-app: samples/modules/thrift/hello/server
   :host-os: unix
   :board: qemu_x86_64
   :conf: "prj.conf ../overlay-tls.conf"
   :goals: run
   :compact:

In another terminal, run the ``hello_client`` sample app compiled for the
host OS:

.. code-block:: console

    $ ./hello_client 192.0.2.1
    $ ./hello_client_compact 192.0.2.1
    $ ./hello_client_ssl 192.0.2.1 ../native-cert.pem ../native-key.pem ../qemu-cert.pem

You should observe the following in the original ``hello/server`` terminal:

.. code-block:: console

    ping
    echo: Hello, world!
    counter: 1
    counter: 2
    counter: 3
    counter: 4
    counter: 5

In the client terminal, run ``hello_client.py`` app under the host OS (not
described for compact or ssl variants for brevity):

.. code-block:: console

    $ ./hello_client.py

You should observe the following in the original ``hello/server`` terminal.
Note that the server's state is not discarded (the counter continues to
increase).

.. code-block:: console

    ping
    echo: Hello, world!
    counter: 6
    counter: 7
    counter: 8
    counter: 9
    counter: 10

Running the Zephyr Client in QEMU
=================================

In another terminal, run the ``hello_server`` sample app compiled for the
host OS:

.. code-block:: console

    $ ./hello_server 0.0.0.0
    $ ./hello_server_compact 0.0.0.0
    $ ./hello_server_ssl 0.0.0.0 ../native-cert.pem ../native-key.pem ../qemu-cert.pem


Then, in annother terminal, run the corresponding ``hello/client`` sample:

.. zephyr-app-commands::
   :zephyr-app: samples/modules/thrift/hello/client
   :board: qemu_x86_64
   :goals: run
   :compact:

The additional arguments for advanced features are the same as
``hello/server``.

You should observe the following in the original ``hello_server`` terminal:

.. code-block:: console

    ping
    echo: Hello, world!
    counter: 1
    counter: 2
    counter: 3
    counter: 4
    counter: 5