:EP: 35
:Title: Kytos stats with OF table stats
:Authors:
    - Gretel Liz De la Peña <gdelapea AT fiu DOT edu>
    - Italo Valcy <idasilva AT fiu DOT edu>
    - Vinicius Arcanjo <vindasil AT fiu DOT edu>
:Created: 2023-03-13
:Kytos-Version: 2023.1
:Status: Finished

***************************************
EP035 - Kytos stats with OF table stats
***************************************

Abstract
========

This blueprint is to support table statistics and concentrate the statistics into a single NApp.

Actions will involve ``flow_stats``, ``of_core`` and Zabbix Wrapper.

Motivation
==========

Currently ``flow_stats`` is responsible to deal with flow statistics, which are exposed in endpoints:

- ``GET v1/flow/stats`` to get the flows stats by ``dpid``.

- ``GET v1/packet_count/<flow_id>`` for packet count of a specific flow.

- ``GET v1/bytes_count/<flow_id>`` for bytes count of a specific flow.

- ``GET v1/packet_count/per_flow/<dpid>`` for packet count per flow.

- ``GET v1/bytes_count/per_flow/<dpid>`` for bytes count per flow.

However, OF table stats are not supported. 

The goal of this blueprint is to evolve ``flow_stats`` into ``kytos_stats`` for kytos statistics, including OF table stats support.

Specification
=============

Information about tables is requested with the ``OFPMP_TABLE`` type of the ``OFPT_MULTIPART_REQUEST`` message. 
The request does not contain any data in the body and the body of the reply consists of an array of struct ``ofp_table_stats``, which contains:

- ``table_id``: Identifier of table.

- ``active_count``: Number of active entries.

- ``lookup_count``: Number of packets looked up in table.

- ``matched_count``: Number of packets that hit table. 

Proposed Changes
----------------

- Create the new napp ``kytos_stats`` from ``flow_stats``. 
- New event from ``of_core``.
- Update ``kytos_stats`` to suport OF table stats.
- Update Zabbix Wrapper.
- Update the routes in the e2e test suite for ``flow_stats`` to ``kytos_stats``.
- Include an e2e test for a new endpoint ``v1/table/stats`` using OvS. 

``of_core``
~~~~~~~~~~~

This napp will support ``MultipartType.OFPMP_TABLE`` and a new event will be published, just so ``kytos_stats`` can subscribe and react accordingly.
Will be requested by switch and sent only when the switch has confirmed its capabilities:

``controller.switches[dpid].features.capabilities.value & Capabilities.OFPC_TABLE_STATS == Capabilities.OFPC_TABLE_STATS``

Published Events
----------------

kytos/of_core.table_stats.received
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Event reporting OF table stats

Content:

.. code-block:: python3

   {
     "switch": <switch>
     "replies_tables": [<Table stats>]
   }


``kytos_stats``
~~~~~~~~~~~~~~

- To build ``kytos_stats``, one forking from ``flow_stats`` will be created and then, ``flow_stats`` will be depreciated. 
It will allow a period for transitions. The network operator will be able to decide to keep both of them running while related tools are reconfigured (Zabbix).

- An equivalent behavior of flow stats to the current one in ``flow_stats`` will be kept.
A data structure will be updated with the ``kytos/of_core.table_stats.received`` event. 
This structure will be indexed by ``dpid`` and ``table_id``, and will allow the following API endpoints to be added:

``GET v1/table/stats`` to get the statistics of tables. Will be provided query parameters filtering by ``dpid`` and optionally by ``table_id``.

.. code-block:: python3

  {
    "dpid_1": {
      0: {"table_id": 0, "active_count": a0, "lookup_count": b0, "matched_count": c0}
      1: {"table_id": 1, "active_count": a1, "lookup_count": b1, "matched_count": c1}
      ...
      n: {"table_id": n, "active_count": an, "lookup_count": bn, "matched_count": cn}
    },
    ...
    "dpid_n": {
      ...
    }
  }

Zabbix Wrapper
~~~~~~~~~~~~~~
- Adapt the zabbix wrapper to send requests to the correct endpoints in ``kytos_stats``.
- Update Zabbix Wrapper to print table stats.

Currently, the zabbix wrapper has the funtion ``print_flow_stats`` that is called with the option 5 and uses ``/flow_stats/v1/flow/stats`` endpoint to print the flow stats. 
This tool will be updated as follows:

- Use ``/kytos_stats/v1/flow/stats`` instead of ``/flow_stats/v1/flow/stats``.

- Support the new ``/kytos_stats/v1/table/stats`` endpoint to get the table stats and add option 6 to call it.

- Evolve ``print_flow_stats`` to ``print_kytos_stats``. 

Update this function to print both flow and table stats (i.e. this funtion will be called with option 5 and 6).
This functionality will allow filtering by switch and additionally by table. 
Then, the argument ``target`` will need a processing since it will be allowed a string with one of the pattern: 1) ``dpid`` or 2) ``dpid:::table_id``.

Future work
===========

- Include the calculations to get statistics from EVCs, which is currently the responsibility of Zabbix wrapper.
- Include statistics for OF PortStats
- Support time series stats like: number of EVCs, number of switches, number of interfaces, links, controller uptime.
- Assess whether it is necessary to include prediction tools from the time series stats.
- Export statistics in other formats, such as the very well used _prometheus dashboard format_
