zephyr/samples/modules/thrift/hello
Chris Friedt bc4374b5fe posix: deprecate POSIX_MAX_FDS and add POSIX_DEVICE_IO
The POSIX_MAX_FDS option does not correspond to any standard
POSIX option. It was used to define the size of the file
descriptor table, which is by no means exclusively used by
POSIX (also net, fs, ...).

POSIX_MAX_FDS is being deprecated in order to ensure that
Zephyr's POSIX Kconfig variables correspond to those defined in
the specification, as of IEEE 1003.1-2017. Namely,
POSIX_OPEN_MAX. CONFIG_POSIX_MAX_OPEN_FILES is being deprecated
for the same reason.

To mitigate any possible layering violations, that option is
not user selectable. It tracks the newly added
CONFIG_ZVFS_OPEN_MAX option, which is native to Zephyr.

With this deprecation, we introduce the following Kconfig
options that map directly to standard POSIX Option Groups by
simply removing "CONFIG_":

* CONFIG_POSIX_DEVICE_IO

Similarly, with this deprecation, we introduce the following
Kconfig options that map directly to standard POSIX Options by
simply removing "CONFIG":

* CONFIG_POSIX_OPEN_MAX

In order to maintain parity with the current feature set, we
introduce the following Kconfig options.

* CONFIG_POSIX_DEVICE_IO_ALIAS_CLOSE
* CONFIG_POSIX_DEVICE_IO_ALIAS_OPEN
* CONFIG_POSIX_DEVICE_IO_ALIAS_READ
* CONFIG_POSIX_DEVICE_IO_ALIAS_WRITE

Gate open(), close(), read(), and write() via the
CONFIG_POSIX_DEVICE_IO Kconfig option and move
implementations into device_io.c, to be conformant with the
spec.

Lastly, stage function names for upcoming ZVFS work, to be
completed as part of the LTSv3 Roadmap (e.g. zvfs_open(), ..).

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
2024-06-04 16:27:12 -05:00
..
client posix: deprecate POSIX_MAX_FDS and add POSIX_DEVICE_IO 2024-06-04 16:27:12 -05:00
server posix: deprecate POSIX_MAX_FDS and add POSIX_DEVICE_IO 2024-06-04 16:27:12 -05:00
hello.thrift
native-cert.pem
native-key.pem
overlay-tls.conf
qemu-cert.pem
qemu-key.pem
README.rst
thrift-layers.png

.. _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
************

- Optional Modules

.. code-block:: console
   :caption: Download optional modules with west

   west config manifest.group-filter -- +optional
   west update

- 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