From a5c4a81c88f8834b92c59967ee346d6acc5994fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Rodr=C3=ADguez?= Date: Mon, 10 Aug 2015 13:24:41 +0200 Subject: [PATCH 1/2] Update documentation --- README.rst | 29 +- doc/README.rst | 55 +-- doc/admin_guide.rst | 394 ------------------ .../admin}/Monitoring_IO_Flows.png | Bin doc/manuals/admin/README.rst | 309 ++++++++++++++ doc/manuals/admin/adapter_cli.rst | 1 - doc/manuals/admin/build_source.rst | 10 +- doc/manuals/admin/logs.rst | 82 +++- doc/manuals/admin/resources.rst | 33 -- .../user/Monitoring_Architecture.png} | Bin ...toring_GE_probe_parser_class_hierarchy.png | Bin .../user/README.rst} | 53 ++- doc/manuals/user/walkthrough_api_v1.rst | 1 - doc/resources/Monitoring_Installation.png | Bin 62709 -> 0 bytes ngsi_adapter/README.rst | 99 +---- ngsi_event_broker/README.rst | 80 ++-- 16 files changed, 511 insertions(+), 635 deletions(-) delete mode 100644 doc/admin_guide.rst rename doc/{resources => manuals/admin}/Monitoring_IO_Flows.png (100%) create mode 100644 doc/manuals/admin/README.rst delete mode 100644 doc/manuals/admin/adapter_cli.rst delete mode 100644 doc/manuals/admin/resources.rst rename doc/{resources/Monitoring_GE_FMC.png => manuals/user/Monitoring_Architecture.png} (100%) rename doc/{resources => manuals/user}/Monitoring_GE_probe_parser_class_hierarchy.png (100%) rename doc/{user_guide.rst => manuals/user/README.rst} (67%) delete mode 100644 doc/manuals/user/walkthrough_api_v1.rst delete mode 100644 doc/resources/Monitoring_Installation.png diff --git a/README.rst b/README.rst index d3a4299..e787d6a 100644 --- a/README.rst +++ b/README.rst @@ -80,7 +80,7 @@ Requirements ------------ - System resources: see `these recommendations - `_. + `_. - Operating systems: CentOS (RedHat) and Ubuntu (Debian), being CentOS 6.3 the reference operating system. - RPM/DEB dependencies: some required packages may not be present in official @@ -175,7 +175,7 @@ command line or as a system service (the latter only available if installed as a package). It is not recommended to mix both ways (e.g. start it manually but use the service scripts to stop it). This section assumes you are using the system service (recommended): for the command line alternative, please refer -to `this document `_. +to `this document `_. In order to start the adapter service, run:: @@ -216,7 +216,7 @@ The configuration used by the adapter service is optionally read from the file All these attributes map to options of the `command line interface -`_ as follows: +`_ as follows: - ``ADAPTER_LOGLEVEL`` maps to ``-l`` or ``--logLevel`` option - ``ADAPTER_LISTEN_HOST`` maps to ``-H`` or ``--listenHost`` option @@ -258,16 +258,8 @@ This would result in an invocation to Context Broker updating the context of an entity of type ``host`` identified by ``myhostname`` with a new attribute ``cpuLoadPct`` with value ``5.00``. -Please have a look at the `Quick Start guide -`_ for more examples. And, additionally, -at the `API Walkthrough`_ and `API Reference Documentation`_ sections bellow -in order to know more details about the API. - - -API Walkthrough ---------------- - -- `FIWARE Monitoring v1 `_ +Please have a look at the `API Reference Documentation`_ section bellow and +at the `programmer guide `_. API Reference Documentation @@ -329,12 +321,17 @@ unit tests. Advanced topics =============== -- Installation and administration +- `Installation and administration `_ * `Building from sources `_ - * `Running Adapter from command line `_ + * `Running Adapter from command line `_ * `Logs `_ - * `Resources & I/O Flows `_ + * `Resources & I/O Flows `_ + +- `User and programmers guide `_ + + * `NGSI Adapter custom probe parsers `_ + * `Retrieval of historical data `_ License diff --git a/doc/README.rst b/doc/README.rst index 2765123..752ee26 100644 --- a/doc/README.rst +++ b/doc/README.rst @@ -1,5 +1,6 @@ -Overview -________ +========== + Overview +========== What you get @@ -12,9 +13,9 @@ be easily extended to collect data for other required needs. Monitoring involves gathering operational data in a running system. Collected information can be used for several purposes: -- Cloud users to track the performance of their own instances. -- SLA management, in order to check adherence to agreement terms. -- Optimization of virtual machines. +- Cloud users to track the performance of their own instances. +- SLA management, in order to check adherence to agreement terms. +- Optimization of virtual machines. The monitoring system is used by different Cloud GEs in order to track the status of the resources. They use gathered data to take decisions about @@ -31,48 +32,48 @@ in the FIWARE Cloud ecosystem in order to monitoring and metering virtual resources. This middleware unify the monitoring and metering solution, providing the following advantages: -- **Full FIWARE integrated solution** +- **Full FIWARE integrated solution** - This component is integrated with the architecture deployed in the FIWARE - and you do not need to do extra work in order to integrate the solution with - the rest of Generic Enabler implementation. + This component is integrated with the architecture deployed in the FIWARE + and you do not need to do extra work in order to integrate the solution with + the rest of Generic Enabler implementation. -- **Non-intrusiveness on resource functionality and performance** +- **Non-intrusiveness on resource functionality and performance** - The Monitoring system not affect the rest of resource functionality nor - performance. + The Monitoring system not affect the rest of resource functionality nor + performance. -- **Deal with metric heterogeneity** +- **Deal with metric heterogeneity** - The Monitoring system deals with different kind of metrics (infrastructure, - KPI, applications and product metrics), different virtualization - technologies, different products, applications, etc. + The Monitoring system deals with different kind of metrics (infrastructure, + KPI, applications and product metrics), different virtualization + technologies, different products, applications, etc. -- **Scalability in monitored resources** +- **Scalability in monitored resources** - The system scales to large numbers of monitored nodes and resources. + The system scales to large numbers of monitored nodes and resources. -- **Service Aggregation** +- **Service Aggregation** - The framework aggregates the monitoring information collected at - application/service level, which means that it aggregates metrics from - virtual machines or hardware resources at service level. + The framework aggregates the monitoring information collected at + application/service level, which means that it aggregates metrics from + virtual machines or hardware resources at service level. Documentation ============= -- `User and Programmers Guide `_ -- `Installation and Administration Guide `_ +- `User and Programmers Guide `_ +- `Installation and Administration Guide `_ See also ======== -- `Monitoring Federation Infrastructure`_ +- `Monitoring Federation Infrastructure`_ - This presentation summarises the development of this component as a joint - task between FIWARE and XIFI projects. + This presentation summarises the development of this component as a joint + task between FIWARE and XIFI projects. .. REFERENCES diff --git a/doc/admin_guide.rst b/doc/admin_guide.rst deleted file mode 100644 index dd5cdcd..0000000 --- a/doc/admin_guide.rst +++ /dev/null @@ -1,394 +0,0 @@ -Installation and Administration Guide -_____________________________________ - - -Introduction -============ - -This guide defines the procedure to install the different components that build -up the Monitoring GE, including its requirements and possible troubleshooting. - - -Installation -============ - -Monitoring infrastructure comprises several elements distributed across -different hosts, as depicted in the following figure: - -.. figure:: resources/Monitoring_Installation.png - :alt: Monitoring installation. - - .. - - #. **Probes**, installed at every host being monitored. - #. **NGSI Adapter**, responsible for translating probe raw data into a - common format (NGSI). - #. **Parsers** at NGSI Adapter, specific for the different probes that - generate monitoring data. - #. **Context Broker GE**, where monitoring data (expressed as "NGSI - context updates") will be published. - #. **Hadoop**, for storing historical context data. - #. **Connector** between Context Broker and data storage. - - -Installation of probes ----------------------- - -Monitoring GE is agnostic to the framework used to gather monitoring data. It -just assumes there are several probes collecting such data, which somehow will -be forwarded to the adaptation layer (NGSI Adapter). - -It is up to the infrastructure owner which tool (like Nagios_, Zabbix_, -openNMS_, perfSONAR_, etc.) is installed for this purpose. - -Probes must "publish" their data to NGSI Adapter. Depending on the exact -monitoring tool installed, a kind of *collector* has to be deployed in -order to send data to the adapter: - -- **NGSI Event Broker** is an example specific for Nagios, implemented as - a loadable module. Description and installation details can be found - `here <../ngsi_event_broker/README.rst>`_. - - -Installation of NGSI Adapter ----------------------------- - -Requirements -~~~~~~~~~~~~ - -NGSI Adapter should work on a variety of operating systems, particularly on the -majority of GNU/Linux distributions (e.g. Debian, Ubuntu, CentOS), as it only -requires a V8 JavaScript Engine to run a Node.js server. - -Hardware Requirements -^^^^^^^^^^^^^^^^^^^^^ - -The minimal requirements are: - -- RAM: 2 GB - - -Software Requirements -^^^^^^^^^^^^^^^^^^^^^ - -NGSI Adapter is a standalone Node.js process, so ``node`` and its package -manager ``npm`` should be installed previously. These requirements are -automatically checked when installing the ``fiware-monitoring-ngsi-adapter`` -package. However, for manual installation please check -\ https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager\ : - -- Manual installation of Node.js in Ubuntu - -.. code:: - - $ curl -sL https://deb.nodesource.com/setup | sudo bash - - $ sudo apt-get install nodejs - - -- Manual installation of Node.js in Debian (as root) - -.. code:: - - # apt-get install curl - # curl -sL https://deb.nodesource.com/setup | bash - - # apt-get install nodejs nodejs-legacy - - -- Manual installation of Node.js in CentOS (requires EPEL: Extra Packages - for Enterprise Linux) - -.. code:: - - $ sudo yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm - $ sudo yum install nodejs npm --enablerepo=epel - - -Downloads -~~~~~~~~~ - -Packages for Ubuntu 12.04 LTS and CentOS 6.3 are available for download. Please -refer to the download__ section of FIWARE Catalogue. You can use tools such as -``gdebi`` or ``rpm`` to install the downloaded files: - -__ `Catalogue - Monitoring download`_ - -.. code:: - - ubuntu$ sudo gdebi fiware-monitoring-ngsi-adapter_X.Y.Z_all.deb - centos$ sudo rpm -i fiware-monitoring-ngsi-adapter-X.Y.Z-N.noarch.rpm - -For the latest version, please download zip from -\ https://github.com/telefonicaid/fiware-monitoring/archive/master.zip\ . -This includes the *ngsi_adapter* directory corresponding to the NGSI Adapter -component. - -.. code:: - - $ unzip fiware-monitoring-master.zip - $ cd fiware-monitoring-master/ - - -Dependencies -~~~~~~~~~~~~ - -NGSI Adapter requires some packages, which can be installed using the ``npm`` -package manager. In case of manual installation from sources, please run: - -.. code:: - - $ cd ngsi_adapter/src - $ npm install - - -Installation of parsers ------------------------ - -NGSI Adapter currently includes a predefined set of parsers for Nagios probes -at ``src/lib/parsers/`` directory, each parser named after its corresponding -probe. New custom parsers should be placed here. - - -Installation of Context Broker GE ---------------------------------- - -Please refer to `Orion Context Broker - Installation and Administration Guide`__ -for installation details. - -__ `Orion - Admin guide`_ - - -Installation of the connector ------------------------------ - -This component subscribes to changes at Context Broker and writes data into a -distributed filesystem storage (usually HDFS from Hadoop_). Historically the -**ngsi2cosmos** connector implementation has been used (installation details -here__), although from March 2014 this component is deprecated and a brand new -**Cygnus** implementation (installation details here__) is available. - -__ `ngsi2cosmos`_ -__ `Cygnus`_ - - -Running the monitoring components -================================= - -As stated before, there are a number of distributed components involved in the -monitoring. Please refer to their respective installation manuals for execution -details (this applies to probes & monitoring software, Context Broker, Hadoop, -etc.). This section focuses on NGSI Adapter specific instructions. - - -Running NGSI Adapter --------------------- - -Once installed, there are two ways of running NGSI Adapter: manually from the -command line or as a system service. It is not recommended to mix both ways -(e.g. start it manually but using the service scripts to stop it). - -From the command line -~~~~~~~~~~~~~~~~~~~~~ - -You can run the adapter just typing the following command from -``ngsi_adapter/src/`` directory: - -.. code:: - - $ adapter - - -You can use command line arguments, e.g. to specify the port in adapter listens: - -.. code:: - - $ adapter --listenPort 5000 - - -Help for command line options: - -.. code:: - -  $ adapter --help - - -As system service -~~~~~~~~~~~~~~~~~ - -When installed from its package distribution, a Linux service ``ngsi_adapter`` -is configured (but not started). The following variables should be checked at -``/etc/init.d/ngsi_adapter`` script prior starting the service: - -DAEMON - Full path of ``adapter`` script -DAEMON\_ARGS - Command line arguments -DAEMON\_USER - Linux user to run service -LOGFILE - Logging file - - -Once the service has been configured, the following commands are available to -control its execution: - -.. code:: - - $ sudo service ngsi_adapter start - $ sudo service ngsi_adapter stop - $ service ngsi_adapter status - - -Configuration options -~~~~~~~~~~~~~~~~~~~~~ - -These options can be used directly (in the case of running from the command -line, but prepending ``--`` prefix) or as part of the default configuration -(see ``defaults`` at the configuration file -``ngsi_adapter/src/config/options.js``): - -logLevel - Verbosity of log messages -listenHost - The hostname or address at which NGSI Adapter listens -listenPort - The port number at which NGSI Adapter listens -brokerUrl - The URL of the Context Broker instance to publish data to -retries - Number of times a request to Context Broker is retried, in case of error - - -Sanity check procedures -======================= - -These are the steps that a System Administrator will take to verify that an -installation is ready to be tested. This is therefore a preliminary set of -tests to ensure that obvious or basic malfunctioning is fixed before proceeding -to unit tests, integration tests and user validation. - - -End to End testing ------------------- - -- At the monitored host, reschedule some probe execution to force the - generation of new monitoring data. - -- Check NGSI Adapter logs for incoming requests with raw data and - outgoing Context Broker requests as NGSI updateContext() operations: - -.. code:: - - $ cat ngsi_adapter.log - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Request on resource /check_xxx with params id=xxx&type=xxx - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Response status 200 OK - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=UpdateContext | msg=Request to ContextBroker at http://cbhost:1026/... - - -- Finally, query Context Broker for new data (see details here__) - -__ `Orion - queryContext`_ - - -List of Running Processes -------------------------- - -A ``node`` process running the "adapter" server should be up and running, e.g.: - -.. code:: - - $ ps -C node -f | grep adapter - fiware   21930     1  0 Mar28 ?        00:06:06 node /opt/fiware/ngsi_adapter/src/adapter - - -Alternatively, we can check if service is running, e.g.: - -.. code:: - - $ service ngsi_adapter status -   * ngsi_adapter is running - - -Network interfaces Up & Open ----------------------------- - -NGSI Adapter uses TCP 1337 as default port, although it can be changed using -the ``--listenPort`` command line option. - - -Databases ---------- - -This component does not persist any data, and no database engine is needed. - - -Diagnosis Procedures -==================== - -The Diagnosis Procedures are the first steps that a System Administrator will -take to locate the source of an error in a GE. Once the nature of the error is -identified with these tests, the system admin will very often have to resort to -more concrete and specific testing to pinpoint the exact point of error and a -possible solution. Such specific testing is out of the scope of this section. - - -Resource availability ---------------------- - -Although we haven't done yet a precise profiling on NGSI Adapter, tests done in -our development and testing environment show that a host with 2 CPU cores and -4 GB RAM is fine to run server. - - -Remote Service Access ---------------------- - -- Probes at monitored hosts should have access to NGSI Adapter listen - port (TCP 1337, by default) - -- NGSI Adapter should have access to Context Broker listen port (TCP 1026, - by default) - -- Connector should have access to Context Broker listen port in order - to subscribe to context changes - -- Context Broker should have access to Connector callback port to notify - changes - - -Resource consumption --------------------- - -Please refer to `Context Broker`__ resource consumption sections. - -__ `Resource consumption - Orion`_ - - -I/O flows ---------- - -Figure at `installation section <#Installation>`_ shows the I/O flows among -the different monitoring components: - -- Probes send requests to NGSI Adapter with raw monitoring data - -- NGSI Adapter sends request to Context Broker in terms of context - updates of the monitored resources - -- Context Broker notifies Connector with every context change - -- Connector writes changes to storage - - -.. REFERENCES - -.. _Catalogue - Monitoring download: http://catalogue.fiware.org/enablers/monitoring-ge-fiware-implementation/downloads -.. _Resource consumption - Orion: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Publish/Subscribe_Broker_-_Orion_Context_Broker_-_Installation_and_Administration_Guide#Resource_consumption -.. _Orion - queryContext: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Publish/Subscribe_Broker_-_Orion_Context_Broker_-_User_and_Programmers_Guide#Query_Context_operation -.. _Orion - Admin guide: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Publish/Subscribe_Broker_-_Orion_Context_Broker_-_Installation_and_Administration_Guide -.. _ngsi2cosmos: https://github.com/telefonicaid/fiware-livedemoapp#ngsi2cosmos -.. _Cygnus: https://github.com/telefonicaid/fiware-cygnus/tree/master -.. _Nagios: http://www.nagios.org/ -.. _Zabbix: http://www.zabbix.com/ -.. _openNMS: http://www.opennms.org/ -.. _perfSONAR: http://www.perfsonar.net/ -.. _Hadoop: http://hadoop.apache.org/ diff --git a/doc/resources/Monitoring_IO_Flows.png b/doc/manuals/admin/Monitoring_IO_Flows.png similarity index 100% rename from doc/resources/Monitoring_IO_Flows.png rename to doc/manuals/admin/Monitoring_IO_Flows.png diff --git a/doc/manuals/admin/README.rst b/doc/manuals/admin/README.rst new file mode 100644 index 0000000..9b60866 --- /dev/null +++ b/doc/manuals/admin/README.rst @@ -0,0 +1,309 @@ +======================================= + Installation and Administration Guide +======================================= + +Introduction +============ + +This guide defines the procedure to install the different components that build +up the Monitoring GE, including its requirements and possible troubleshooting. + +For general information, please refer to `this document `_. + + +Installation +============ + +Monitoring infrastructure comprises several elements distributed across +different hosts, as depicted in the following figure: + +.. figure:: Monitoring_IO_Flows.png + :alt: Monitoring components. + + .. + + #. **Probes** gather raw monitoring data, which a **Collector** (for Nagios, + this is *NGSI Event Broker*) forwards to *NGSI Adapter*. + #. **NGSI Adapter**, responsible for translating probe raw data into a + common format (NGSI). + #. **Parsers** at NGSI Adapter, specific for the different probes that + generate monitoring data. + #. **Context Broker**, where monitoring data (transformed into NGSI context + updates) will be published. + #. **Hadoop**, for storing historical context data. + #. **Connector** between Context Broker and data storage (for example, this + could be *Cygnus*). + + +Installation of probes +---------------------- + +Monitoring GE is agnostic to the framework used to gather monitoring data. It +just assumes there are several probes collecting such data, which somehow will +be forwarded to the adaptation layer (NGSI Adapter). + +It is up to the infrastructure owner which tool (like Nagios_, Zabbix_, +openNMS_, perfSONAR_, etc.) is installed for this purpose. + + +Installation of collector +------------------------- + +Probes must "publish" their data to NGSI Adapter. Depending on the exact +monitoring tool installed, a kind of *collector* has to be deployed in +order to send data to the adapter: + +- **NGSI Event Broker** is an example specific for Nagios, implemented as + a loadable module. Description and installation details can be found + `here `_. + + +Installation of NGSI Adapter +---------------------------- + +Requirements +~~~~~~~~~~~~ + +NGSI Adapter should work on a variety of operating systems, particularly on the +majority of GNU/Linux distributions (e.g. Debian, Ubuntu, CentOS), as it only +requires a V8 JavaScript Engine to run a Node.js server. + +Hardware Requirements +^^^^^^^^^^^^^^^^^^^^^ + +The minimal requirements are: + +- RAM: 2 GB + + +Software Requirements +^^^^^^^^^^^^^^^^^^^^^ + +NGSI Adapter is a standalone Node.js process, so ``node`` and its package +manager ``npm`` should be installed previously. These requirements are +automatically checked when installing the ``fiware-monitoring-ngsi-adapter`` +package. However, for manual installation please visit NodeSource_. + + +Downloads +~~~~~~~~~ + +Please refer to `this document `_ for details. + + +Additional parsers +~~~~~~~~~~~~~~~~~~ + +NGSI Adapter currently includes a predefined set of parsers for Nagios probes +at ``lib/parsers/`` directory, each parser named after its corresponding probe. + +Whenever new Nagios probes are used, or even if we decide to use a different +monitoring framework with its own set of probes, the corresponding parsers +should be dropped in such directory. + + +Installation of Context Broker +------------------------------ + +Please refer to Orion_ documentation. + + +Installation of the connector +----------------------------- + +This component subscribes to changes at Context Broker and writes data into a +distributed filesystem storage (usually HDFS from Hadoop_). Historically the +**ngsi2cosmos** connector implementation has been used (installation details +here__), although from March 2014 this component is deprecated and a brand new +**Cygnus** implementation (installation details here__) is available. + +__ `ngsi2cosmos`_ +__ `Cygnus`_ + + +Running the monitoring components +================================= + +As stated before, there are a number of distributed components involved in the +monitoring. Please refer to their respective installation manuals for execution +details (this applies to probes & monitoring software, Context Broker, Hadoop, +etc.). This section focuses on NGSI Adapter specific instructions. + + +Running NGSI Adapter +-------------------- + +Once installed, there are two ways of running NGSI Adapter: manually from the +command line or as a system service. It is not recommended to mix both ways +(e.g. start it manually but using the service scripts to stop it). + + +As system service +~~~~~~~~~~~~~~~~~ + +When installed from its package distribution, a Linux service ``ngsi_adapter`` +is configured (but not started). Please refer to `this document +`_ for details. + + +From the command line +~~~~~~~~~~~~~~~~~~~~~ + +You can run the adapter just typing the following command at the installation +directory (usually ``/opt/fiware/ngsi_adapter/``): + +.. code:: + + $ adapter + + +You can use these command line options (available typing ``adapter --help``): + +-l, --logLevel + Verbosity of log messages +-H, --listenHost + The hostname or address at which NGSI Adapter listens +-p, --listenPort + The port number at which NGSI Adapter listens +-b, --brokerUrl + The URL of the Context Broker instance to publish data to +-r, --retries + Number of times a request to Context Broker is retried, in case of error + + +Sanity check procedures +======================= + +These are the steps that a System Administrator will take to verify that an +installation is ready to be tested. This is therefore a preliminary set of +tests to ensure that obvious or basic malfunctioning is fixed before proceeding +to unit tests, integration tests and user validation. + + +End to end testing +------------------ + +- Use the commands of the monitoring framework being used (for example, Nagios) + to reschedule some probe execution and force the generation of new monitoring + data. + +- Check NGSI Adapter logs for incoming requests with raw data, and check the + outgoing Context Broker requests as NGSI updateContext() operations: + +.. code:: + + $ cat /var/log/ngsi_adapter/ngsi_adapter.log + time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Request on resource /check_xxx with params id=xxx&type=xxx + time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Response status 200 OK + time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=UpdateContext | msg=Request to ContextBroker at http://host:1026/... + + +- Finally, query Context Broker API to check whether entity attributes have + been updated according to the new monitoring data (see details here__) + +__ Orion_ + + +List of Running Processes +------------------------- + +A ``node`` process running the "adapter" server should be up and running, e.g.: + +.. code:: + + $ ps -C node -f | grep adapter + fiware   21930     1  0 Mar28 ?        00:06:06 node /opt/fiware/ngsi_adapter/src/adapter + + +Alternatively, we can check if service is running, e.g.: + +.. code:: + + $ service ngsi_adapter status + * ngsi_adapter is running + + +Network interfaces Up & Open +---------------------------- + +NGSI Adapter uses TCP 1337 as default port, although it can be changed using +the ``--listenPort`` command line option. + + +Databases +--------- + +This component does not persist any data, and no database engine is needed. + + +Diagnosis Procedures +==================== + +The Diagnosis Procedures are the first steps that a System Administrator will +take to locate the source of an error in a GE. Once the nature of the error is +identified with these tests, the system admin will very often have to resort to +more concrete and specific testing to pinpoint the exact point of error and a +possible solution. Such specific testing is out of the scope of this section. + + +Resource availability +--------------------- + +Although we haven't done yet a precise profiling on NGSI Adapter, tests done in +our development and testing environment show that a host with 2 CPU cores and +4 GB RAM is fine to run server. + + +Remote service access +--------------------- + +- Probes at monitored hosts should have access to NGSI Adapter listen + port (TCP 1337, by default) + +- NGSI Adapter should have access to Context Broker listen port (TCP 1026, + by default) + +- Connector should have access to Context Broker listen port in order + to subscribe to context changes + +- Context Broker should have access to Connector callback port to notify + changes + + +Resource consumption +-------------------- + +No issues related to resources consumption have been detected neither with +the NGSI Adapter server nor with the NGSI Event Broker loaded as a "pluggable" +module on Nagios startup. + + +I/O flows +--------- + +Figure at `installation section`__ shows the I/O flows among the different +monitoring components: + +__ `Installation`_ + +- Probes send requests to NGSI Adapter with raw monitoring data + +- NGSI Adapter sends request to Context Broker in terms of context + updates of the monitored resources + +- Context Broker notifies Connector with every context change + +- Connector writes changes to storage + + +.. REFERENCES + +.. _Orion: https://github.com/telefonicaid/fiware-orion/ +.. _Cygnus: https://github.com/telefonicaid/fiware-cygnus/ +.. _ngsi2cosmos: https://github.com/telefonicaid/fiware-livedemoapp#ngsi2cosmos +.. _NodeSource: https://github.com/nodesource/distributions/ +.. _Hadoop: http://hadoop.apache.org/ +.. _Nagios: http://www.nagios.org/ +.. _Zabbix: http://www.zabbix.com/ +.. _openNMS: http://www.opennms.org/ +.. _perfSONAR: http://www.perfsonar.net/ diff --git a/doc/manuals/admin/adapter_cli.rst b/doc/manuals/admin/adapter_cli.rst deleted file mode 100644 index 8f9c827..0000000 --- a/doc/manuals/admin/adapter_cli.rst +++ /dev/null @@ -1 +0,0 @@ -TO-DO \ No newline at end of file diff --git a/doc/manuals/admin/build_source.rst b/doc/manuals/admin/build_source.rst index 0491837..a58b15e 100644 --- a/doc/manuals/admin/build_source.rst +++ b/doc/manuals/admin/build_source.rst @@ -27,7 +27,7 @@ special privileges): - Install development tools:: $ sudo yum install -y gcc-c++ make rpm-build redhat-rpm-config - $ sudo npm install -g grunt-cli + $ sudo npm install -g grunt-cli - Get the source code from GitHub:: @@ -42,7 +42,7 @@ special privileges): - (Optional but highly recommended) check coding style, run unit tests and get coverage:: - $ grunt lint test coverage + $ grunt lint test coverage - At this point, we are ready to run the server manually:: @@ -85,6 +85,10 @@ a valid Makefile to drive the build and install process. $ mkdir -p m4 && autoreconf -i $ ./configure --enable-gcov --with-nagios-srcdir=$NAGIOS_SRC_DIR +- Default installation directory is ``/opt/fiware/ngsi_event_broker/lib``. The + target directory may be changed by adding ``--libdir=target_libdir`` option + when running the ``configure`` script. + - Compile and check coding style, run unit tests and get coverage (optional but highly recommended):: @@ -111,7 +115,7 @@ NGSI Adapter - Install development tools:: $ sudo apt-get install -y g++ make dpkg-dev debhelper devscripts - $ sudo npm install -g grunt-cli + $ sudo npm install -g grunt-cli NGSI Event Broker diff --git a/doc/manuals/admin/logs.rst b/doc/manuals/admin/logs.rst index 8f9c827..845cded 100644 --- a/doc/manuals/admin/logs.rst +++ b/doc/manuals/admin/logs.rst @@ -1 +1,81 @@ -TO-DO \ No newline at end of file +====== + Logs +====== + +The log system has been re-worked in release `4.1.1`__. This section describes +its main characteristics. + +__ `FIWARE Monitoring release 4.1.1`_ + + +Log file +======== + +The *NGSI Adapter* component of Monitoring GE writes logs, when running as a +service, to the file ``/var/log/ngsi_adapter/ngsi_adapter.log`` (if started +manually from command line, logs are written to standard output). + +The *NGSI Event Broker* component is a module integrated into the *Nagios* +framework and its logs are written to the file ``/var/log/nagios/nagios.log`` +(or any other defined by Nagios configuration). + + +Log format +========== + +The log format is designed to be processed by tools like Splunk_ or Fluentd_. + +Each line in the log file is composed by several key-value fields, separated +by the pipe character (``|``). Example: + +:: + + time=2015-08-01T08:00:00.511Z | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Request on resource /check_xxx with params id=xxx&type=xxx + time=2015-08-01T08:00:00.675Z | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Response status 200 OK + time=2015-08-01T08:00:00.922Z | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=UpdateContext | msg=Request to ContextBroker at http://host:1026/... + + +These are the different fields found in each line: + +- **time**. A timestamp corresponding to the moment in which the log line was + generated. + +- **lvl (level)**. One of the following: + + * INFO: This level designates informational messages that highlight the + progress of the component. + * WARNING: This level designates potentially harmful situations. There is + a minor problem that should be fixed. + * ERROR: This level designates error events. There is a severe problem that + should be fixed. + * FATAL: This level designates very severe error events that will presumably + lead the application to abort. The process can no longer work. + * DEBUG: This level designates fine-grained informational events that are + most useful to debug an application. + +- **trans (transaction id)**. Can be either "N/A" (for log messages "out of + transaction", as the ones corresponding to startup) or a unique string id. + +- **op (operation)**. The function in the source code that generated the log + message. This information is useful for developers only. + +- **msg (message)**. The actual log message. + + +Log rotation +============ + +The system administrator **must** configure some log rotation mechanism, or +otherwise the log file size will increase indefinitely. We recommend using +logrotate_. + +Depending on your expected work load, you would need to adjust the rotation +parameters. + + +.. REFERENCES + +.. _Splunk: http://www.splunk.com/ +,. _Fluentd: http://www.fluentd.org/ +.. _logrotate: http://linux.die.net/man/8/logrotate +.. _FIWARE Monitoring release 4.1.1: https://github.com/telefonicaid/fiware-monitoring/releases/tag/v4.1.1 diff --git a/doc/manuals/admin/resources.rst b/doc/manuals/admin/resources.rst deleted file mode 100644 index 7a25887..0000000 --- a/doc/manuals/admin/resources.rst +++ /dev/null @@ -1,33 +0,0 @@ -======================= - Resources & I/O Flows -======================= - -Resources recommendations -========================= - -Although we haven't done yet a precise profiling on the NGSI Adapter component -of this Monitoring GE, tests done in our development and testing environment -show that a host with 2 CPU cores and 4 GB RAM is fine to run server. - -Resources consumption -===================== - -No issues related to resources consumption have been detected neither with -the NGSI Adapter server nor with the NGSI Event Broker loaded as a "pluggable" -module on Nagios startup. - -I/O flows -========= - -Figure below shows the I/O flows among the different monitoring components: - -.. figure:: /doc/resources/Monitoring_IO_Flows.png - :alt: Monitoring I/O flows. - -- The probes gather raw monitoring data, and a Collector (for Nagios, this is - *NGSI Event Broker*) send requests to *NGSI Adapter* with such data -- NGSI Adapter sends request to *Context Broker* in terms of context updates - of the monitored resources -- Context Broker notifies a *Connector* (for example, Cygnus) with every change - in the context of entities -- The connector writes changes to storage diff --git a/doc/resources/Monitoring_GE_FMC.png b/doc/manuals/user/Monitoring_Architecture.png similarity index 100% rename from doc/resources/Monitoring_GE_FMC.png rename to doc/manuals/user/Monitoring_Architecture.png diff --git a/doc/resources/Monitoring_GE_probe_parser_class_hierarchy.png b/doc/manuals/user/Monitoring_GE_probe_parser_class_hierarchy.png similarity index 100% rename from doc/resources/Monitoring_GE_probe_parser_class_hierarchy.png rename to doc/manuals/user/Monitoring_GE_probe_parser_class_hierarchy.png diff --git a/doc/user_guide.rst b/doc/manuals/user/README.rst similarity index 67% rename from doc/user_guide.rst rename to doc/manuals/user/README.rst index e075f04..7185b58 100644 --- a/doc/user_guide.rst +++ b/doc/manuals/user/README.rst @@ -1,5 +1,6 @@ -User and Programmers Guide -__________________________ +============================ + User and Programmers Guide +============================ Introduction @@ -9,7 +10,7 @@ Welcome the User and Programmers Guide for the Monitoring Generic Enabler. This GE is built up from different distributed components, as depicted in the following figure: -.. figure:: resources/Monitoring_GE_FMC.png +.. figure:: Monitoring_Architecture.png :alt: Monitoring GE architecture overview. .. @@ -19,8 +20,11 @@ Background and Detail --------------------- This User and Programmers Guide relates to the Scalability Manager GE which is -part of the `Cloud Hosting Chapter`_. Please find more information about this -Generic Enabler in the following `Open Specification`_. +part of the `Cloud Hosting Chapter`__. Please find more information about this +Generic Enabler in the following `Open Specification`__. + +__ `FIWARE Cloud Hosting Chapter`_ +__ `FIWARE Monitoring - Open Specification`_ User Guide @@ -55,19 +59,18 @@ For example, given the following scenario: then requests would look like:: - HTTP POST http://adapterhost:1337/check_load?id=178.23.5.23&type=host - Content-Type: text/plain - OK - load average: 0.36, 0.25, 0.24|load1=0.360;1.000;1.000;0; load5=0.250;5.000;5.000;0; load15=0.240;15.000;15.000;0; + HTTP POST http://adapterhost:1337/check_load?id=178.23.5.23&type=host + Content-Type: text/plain + OK - load average: 0.36, 0.25, 0.24|load1=0.360;1.000;1.000;0; load5=0.250;5.000;5.000;0; load15=0.240;15.000;15.000;0; Please take into account that NGSI standard identify entities (in this case, the resources being monitored) using a pair <*entityId*,\ *entityType*>. This identification of the monitored resource has to be provided as the query parameters ``id`` and ``type``, respectively. The probe name included in the URL lets NGSI Adapter know the originating monitoring probe, therefore -selecting the proper parser for it. This API is fully described in -`docs.fiwaremonitoring.apiary.io`__ +selecting the proper parser for it. This API is fully described in Apiary__. -__ `Monitoring NGSI Adapter API`_ +__ `FIWARE Monitoring - NGSI Adapter API`_ Monitoring framework is expected to schedule the execution of probes and send the raw data been gathered to the NGSI Adapter. Depending on the tool that has @@ -75,6 +78,10 @@ been chosen, this would require the development of a custom component (a kind of **monitoring collector**) to automatically forward such data to the adaptation layer. + +NGSI Adapter parsers +-------------------- + NGSI Adapter processes requests asynchronously, trying to locate a valid parser named after the originating probe, located at ``lib/parsers/``. If probe is unknown, response status will be ``404``; otherwise, response status will be @@ -87,7 +94,7 @@ extending a base abstract object and implementing the aforementioned methods. For example, suppose we want to support a new "*myProbe*\ " whose data is a comma-separated list of values of two attributes *myAttr0* and *myAttr1*: -.. figure:: resources/Monitoring_GE_probe_parser_class_hierarchy.png +.. figure:: Monitoring_GE_probe_parser_class_hierarchy.png :alt: Probe parser class hierarchy. .. @@ -115,22 +122,26 @@ comma-separated list of values of two attributes *myAttr0* and *myAttr1*: Context Broker API ------------------ -Please refer to `Context Broker Programmers Guide`_. This will give us access -to the last updates of monitoring data available, but not to historic data. +Please refer to `Context Broker documentation`__. This will give us access +to the last updates of monitoring data available, but not to historical data. + +__ `FIWARE Orion Context Broker`_ Monitoring API -------------- Retrieval of historical data stored at a distributed filesystem (e.g. Hadoop) -is handled by the Query Manager component, whose API is described in -`Monitoring Open RESTful API Specification (PRELIMINARY)`_ section. +is handled by the *Query Manager* component, whose API is described in this +`preliminary specification`__. + +__ `FIWARE Monitoring - Query Manager API`_ .. REFERENCES -.. _Cloud Hosting Chapter: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Cloud_Hosting_Architecture -.. _Open Specification: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/FIWARE.OpenSpecification.Cloud.Monitoring -.. _Context Broker Programmers Guide: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Publish/Subscribe_Broker_-_Orion_Context_Broker_-_User_and_Programmers_Guide#Programmers_Guide -.. _Monitoring Open RESTful API Specification (PRELIMINARY): https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Monitoring_Open_RESTful_API_Specification_(PRELIMINARY) -.. _Monitoring NGSI Adapter API: http://docs.fiwaremonitoring.apiary.io/ +.. _FIWARE Cloud Hosting Chapter: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Cloud_Hosting_Architecture +.. _FIWARE Monitoring - Open Specification: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/FIWARE.OpenSpecification.Cloud.Monitoring +.. _FIWARE Monitoring - Query Manager API: https://forge.fiware.org/plugins/mediawiki/wiki/fiware/index.php/Monitoring_Open_RESTful_API_Specification_(PRELIMINARY) +.. _FIWARE Monitoring - NGSI Adapter API: https://jsapi.apiary.io/apis/fiwaremonitoring/reference.html +.. _FIWARE Orion Context Broker: https://github.com/telefonicaid/fiware-orion diff --git a/doc/manuals/user/walkthrough_api_v1.rst b/doc/manuals/user/walkthrough_api_v1.rst deleted file mode 100644 index 8f9c827..0000000 --- a/doc/manuals/user/walkthrough_api_v1.rst +++ /dev/null @@ -1 +0,0 @@ -TO-DO \ No newline at end of file diff --git a/doc/resources/Monitoring_Installation.png b/doc/resources/Monitoring_Installation.png deleted file mode 100644 index 75b9170b5ebd46ec1fdc169e02d96dd86d56abe7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62709 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 diff --git a/ngsi_adapter/README.rst b/ngsi_adapter/README.rst index ffa120c..2a1e86d 100644 --- a/ngsi_adapter/README.rst +++ b/ngsi_adapter/README.rst @@ -1,6 +1,7 @@ -NGSI Adapter -____________ +============== + NGSI Adapter +============== Generic adapter to transform monitoring data from probes to NGSI context attributes, and forward them through a NGSI Context Broker. @@ -9,83 +10,13 @@ attributes, and forward them through a NGSI Context Broker. Installation ============ -Adapter is distributed as a Ubuntu (.deb) or CentOS (.rpm) package. Assuming -FIWARE package repositories are configured, just use the proper tool (such as -``apt-get`` or ``yum``) to install ``fiware-monitoring-ngsi-adapter`` package. -These distributions are currently supported: - -- Ubuntu 12.04 LTS -- CentOS 6.3 - -During installation process, Node.js engine version is checked and package -dependencies are resolved using ``npm`` tool. Upon successful installation, -a Linux service ``ngsi_adapter`` is created. +Please refer to `this document `_ for details. Usage ===== -Adapter runs as a standalone server listening for HTTP POST requests at the -given endpoint. To start the adapter as service, just type: - -.. code:: - - $ sudo service ngsi_adapter start - - -We can also start the adapter manually from the command line: - -.. code:: - - $ cd {installation_path} - $ adapter - - -Context Broker URL, adapter listen port, logging level and other parameters may -be supplied as command line arguments, overriding the default values defined -in *config/options.js*: - -.. code:: - - $ adapter --listenPort 1337 --brokerUrl http://{host}:{port}/ - - -For detailed information about command line options and their defaults, please -run: - -.. code:: - - $ adapter --help - - -To modify the parameters to run the adapter as a service, please set variable -``DAEMON_ARGS`` in */etc/init.d/ngsi\_adapter* script. - - -Requests -======== - -Probe raw data should be sent as body of a POST request to the adapter, -identifying the source entity being monitored in the query fields (for -further information, see `docs.fiwaremonitoring.apiary.io`__): - -__ http://docs.fiwaremonitoring.apiary.io/ - -.. code:: - - POST http://{adapter_endpoint}/{probe}?id={id}&type={type} - -- *{probe}* = name of the originating probe -- *{id}* = identifier of the entity being monitored -- *{type}* = type of the entity - -Adapter processes requests asynchronously, indicating in the response status -code whether *{probe}* is recognized (status 200) or not (404). - -In case of known probes, adapter dynamically loads a custom probe parser -that should be located at *lib/parsers/{probe}.js* and invokes its -*getContextAttrs()* method, passing probe raw data as attribute(s) of -an object *EntityData*. +Please refer to `this document `_ for details. Changelog @@ -93,37 +24,37 @@ Changelog Version 1.2.3 -- Fix problems when uninstalling package +- Fix problems when uninstalling package Version 1.2.2 -- Add .rpm package generation -- Minor bugs resolved +- Add .rpm package generation +- Minor bugs resolved Version 1.2.1 -- Minor bugs resolved +- Minor bugs resolved Version 1.2.0 -- Add new log format (issue #25) +- Add new log format (issue #25) Version 1.1.1 -- Add .deb package generation (issue #16) +- Add .deb package generation (issue #16) Version 1.1.0 -- Add timestamp to entity attributes (issue #4) +- Add timestamp to entity attributes (issue #4) Version 1.0.1 -- NGSI9 and NGSI10 decoupled in update requests by using append action -- Bugfixing: solved errors in update requests +- NGSI9 and NGSI10 decoupled in update requests by using append action +- Bugfixing: solved errors in update requests Version 1.0.0 -- Only Nagios probes (plugins) are supported +- Only Nagios probes (plugins) are supported License diff --git a/ngsi_event_broker/README.rst b/ngsi_event_broker/README.rst index 35aded5..a758e59 100644 --- a/ngsi_event_broker/README.rst +++ b/ngsi_event_broker/README.rst @@ -1,49 +1,21 @@ -NGSI Event Broker -_________________ +=================== + NGSI Event Broker +=================== +Nagios event broker (NEB_) module to forward plugin data to `NGSI Adapter +<../ngsi_adapter/README.rst>`_. Currently, the broker is particularized for +XIFI_ monitoring: -Nagios event broker (NEB_) module to forward plugin data to -`NGSI Adapter <../ngsi_adapter/README.rst>`_. Currently, the -broker is particularized for XIFI_ monitoring: - -- *ngsi\_event\_broker\_xifi* to process plugin executions for XIFI +- *ngsi\_event\_broker\_xifi* to process plugin executions for XIFI Installation ============ The module is an architecture-dependent compiled shared object distributed as -a single library bundled in an Ubuntu (.deb) or CentOS (.rpm) package. Assuming -FIWARE package repositories are configured, just use the proper tool (such as -``apt-get`` or ``yum``) to install ``fiware-monitoring-ngsi-event-broker`` -package. These distributions are currently supported: - -- Ubuntu 12.04 LTS -- CentOS 6.3 - -As an alternative, module can be compiled from sources, either downloaded from -sources repository or as `source code tarball <../README.rst#Releases>`_. -First option requires *autotools* and *libtool* to be installed, in order -to generate configuration script - -.. code:: - - $ mkdir m4 - $ autoreconf --install - -Once ``configure`` script is generated (or downloaded as part of source -tarball), follow these steps: - -.. code:: - - $ ./configure - $ make - $ make check - $ sudo make install +a single library bundled in an Ubuntu (.deb) or CentOS (.rpm) package. -Default installation directory is ``/opt/fiware/ngsi-event-broker/lib``. In -case of manual installation, target directory can be changed by running -``./configure --libdir=target_libdir`` (may require sudoer privileges). +Please refer to `this document `_ for details. Usage @@ -75,7 +47,7 @@ server in response to plugin executions. Service definitions -~~~~~~~~~~~~~~~~~~~ +------------------- Assuming this Nagios host definition: @@ -158,49 +130,49 @@ Changelog Version 1.4.3 -- Fix problems when uninstalling package +- Fix problems when uninstalling package Version 1.4.2 -- Add .rpm package generation -- Minor bugs resolved +- Add .rpm package generation +- Minor bugs resolved Version 1.4.1 -- Minor bugs resolved +- Minor bugs resolved Version 1.4.0 -- Include new log format (issue #25) +- Include new log format (issue #25) Version 1.3.1 -- Add .deb package generation -- Fix error in argument parser +- Add .deb package generation +- Fix error in argument parser Version 1.3.0 -- Include "host\_service" monitoring +- Include "host\_service" monitoring Version 1.2.0 -- Unification into a single \_xifi broker +- Unification into a single \_xifi broker Version 1.1.0 -- Broker splitted into \_snmp and \_host -- IP address as unique identifier (within region) for hosts and vms -- Add region as argument -- Add NRPE support +- Broker splitted into \_snmp and \_host +- IP address as unique identifier (within region) for hosts and vms +- Add region as argument +- Add NRPE support Version 1.0.1 -- Add regions support (value retrieved from a metadata key named - "region") +- Add regions support (value retrieved from a metadata key named + "region") Version 1.0.0 -- Initial release of the module +- Initial release of the module License From 8a4c452bb3cc1f3e5c0c9f3274cb1cc4f17c1562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Rodr=C3=ADguez?= Date: Tue, 11 Aug 2015 12:32:22 +0200 Subject: [PATCH 2/2] Amend end-to-end and acceptance testing --- README.rst | 31 ++--- doc/manuals/admin/README.rst | 41 ++++--- ngsi_adapter/src/test/acceptance/README.rst | 118 +++++++++++++------- 3 files changed, 115 insertions(+), 75 deletions(-) diff --git a/README.rst b/README.rst index e787d6a..7891dd4 100644 --- a/README.rst +++ b/README.rst @@ -276,25 +276,8 @@ Testing End-to-end tests ---------------- -Use the commands of the monitoring framework being used (for example, Nagios) -to reschedule some probe execution and force the generation of new monitoring -data. - -Check NGSI Adapter logs for incoming requests with raw data, and check the -outgoing Context Broker requests as NGSI updateContext() operations: - -:: - - $ cat /var/log/ngsi_adapter/ngsi_adapter.log - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Request on resource /check_xxx with params id=xxx&type=xxx - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Response status 200 OK - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=UpdateContext | msg=Request to ContextBroker at http://host:1026/... - - -Finally, query Context Broker API to check whether entity attributes have been -updated according to the new monitoring data (see details here__) - -__ `FIWARE Orion Context Broker`_ +Please refer to the `Installation and administration guide +`_ for details. Unit tests @@ -318,6 +301,16 @@ information about how to prepare the environment to run the unit tests. +Acceptance tests +---------------- + +In the following documents you will find a business readable description of the +features provided by the components of the Monitoring GE, as well as automated +tests for them: + +- `NGSI Adapter acceptance tests `_ + + Advanced topics =============== diff --git a/doc/manuals/admin/README.rst b/doc/manuals/admin/README.rst index 9b60866..4b4ab9b 100644 --- a/doc/manuals/admin/README.rst +++ b/doc/manuals/admin/README.rst @@ -117,8 +117,8 @@ distributed filesystem storage (usually HDFS from Hadoop_). Historically the here__), although from March 2014 this component is deprecated and a brand new **Cygnus** implementation (installation details here__) is available. -__ `ngsi2cosmos`_ -__ `Cygnus`_ +__ ngsi2cosmos_ +__ Cygnus_ Running the monitoring components @@ -183,20 +183,24 @@ to unit tests, integration tests and user validation. End to end testing ------------------ -- Use the commands of the monitoring framework being used (for example, Nagios) - to reschedule some probe execution and force the generation of new monitoring - data. +Use the commands of the monitoring framework being used (for example, Nagios) +to reschedule some probe execution and force the generation of new monitoring +data: -- Check NGSI Adapter logs for incoming requests with raw data, and check the - outgoing Context Broker requests as NGSI updateContext() operations: +- Check the logs of the framework (i.e. ``/var/log/nagios/nagios.log``) for + a new probe execution detected by the *collector*:: + + $ cat /var/log/nagios/nagios.log + [1439283831] lvl=INFO | trans=rdPmJ/uHE62a | comp=fiware-monitoring-ngsi-event-broker | op=NGSIAdapter | msg=Request sent to http://host:1337/check_xxx?id=xxx&type=host -.. code:: - $ cat /var/log/ngsi_adapter/ngsi_adapter.log - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Request on resource /check_xxx with params id=xxx&type=xxx - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=POST | msg=Response status 200 OK - time=... | lvl=INFO | trans=ci2627bx00000b42g8m2pxw3z | op=UpdateContext | msg=Request to ContextBroker at http://host:1026/... +- Check NGSI Adapter logs for incoming requests with raw data, and for the + corresponding updateContext() request to Context Broker:: + $ cat /var/log/ngsi_adapter/ngsi_adapter.log + time=... | lvl=INFO | trans=rdPmJ/uHE62a | op=POST | msg=Request on resource /check_xxx with params id=xxx&type=xxx + time=... | lvl=INFO | trans=rdPmJ/uHE62a | op=POST | msg=Response status 200 OK + time=... | lvl=INFO | trans=rdPmJ/uHE62a | op=UpdateContext | msg=Request to ContextBroker at http://host:1026/... - Finally, query Context Broker API to check whether entity attributes have been updated according to the new monitoring data (see details here__) @@ -211,16 +215,16 @@ A ``node`` process running the "adapter" server should be up and running, e.g.: .. code:: - $ ps -C node -f | grep adapter - fiware   21930     1  0 Mar28 ?        00:06:06 node /opt/fiware/ngsi_adapter/src/adapter + $ ps -C node -f | grep adapter + fiware   21930     1  0 Mar28 ?        00:06:06 node /opt/fiware/ngsi_adapter/src/adapter Alternatively, we can check if service is running, e.g.: .. code:: - $ service ngsi_adapter status - * ngsi_adapter is running + $ service ngsi_adapter status + * ngsi_adapter is running Network interfaces Up & Open @@ -284,9 +288,10 @@ I/O flows Figure at `installation section`__ shows the I/O flows among the different monitoring components: -__ `Installation`_ +__ Installation_ -- Probes send requests to NGSI Adapter with raw monitoring data +- Probes send requests to NGSI Adapter with raw monitoring data, by means + of a custom *collector* component (for example, NGSI Event Broker) - NGSI Adapter sends request to Context Broker in terms of context updates of the monitored resources diff --git a/ngsi_adapter/src/test/acceptance/README.rst b/ngsi_adapter/src/test/acceptance/README.rst index 101106a..601a581 100644 --- a/ngsi_adapter/src/test/acceptance/README.rst +++ b/ngsi_adapter/src/test/acceptance/README.rst @@ -1,19 +1,20 @@ -========================================================== -FIWARE-MONITORING | NGSI-Adapter | Acceptance test project -========================================================== +=============================== + NGSI Adapter acceptance tests +=============================== -This project contains the NGSI-Adapter acceptance tests (component, integration and E2E testing). -All test cases have been defined using Gherkin that it is a Business Readable, Domain Specific Language that lets you -describe software’s behaviour without detailing how that behaviour is implemented. -Gherkin has the purpose of serving documentation of test cases. +This project contains the NGSI Adapter acceptance tests (component, integration +and E2E testing). All test cases have been defined using Gherkin_, that it is a +Business Readable, Domain Specific Language that lets you describe software’s +behaviour without detailing how that behaviour is implemented. Gherkin has the +purpose of serving documentation of test cases. +Test case implementation has been performed using Python_ and Lettuce_. -Test case implementation has been performed using `Python `_ and -`Lettuce `_. Acceptance Project Structure ----------------------------- - :: +============================ + +:: ├───acceptance │ ├───commons @@ -29,34 +30,35 @@ Acceptance Project Structure FIWARE Monitoring Automation Framework ---------------------------------------- +====================================== Features: - Lettuce-Tools support - Settings using json files and Lettuce-Tools utility - Test report using Lettuce-Tools XUnit output -- NGSI-Adapter Client +- NGSI Adapter Client - Logging -- Remote NGSI-Adapter log capturing +- Remote NGSI Adapter log capturing - Test data management using templates (resources) -Acceptance test execution -------------------------- +Acceptance tests execution +========================== Execute the following command in the test project root directory: :: - $> cd ngsi_adapter/src/test/acceptance - $> lettuce_tools -ft send_data_api_resource -ts comp -sd features/ --tags=-skip -en dev + $ cd ngsi_adapter/src/test/acceptance + $ lettuce_tools -ft send_data_api_resource -ts comp -sd features/ --tags=-skip -en dev With this command, you will execute: -- components Test Cases in the 'Development' environment configured in settings/dev-properties.json -- the send_data_api_resource feature -- Skipping all Scenarios with tagged with "skip" +- Components test cases in the "Development" environment configured in file + ``settings/dev-properties.json`` +- The "send_data_api_resource" feature +- Skipping all scenarios tagged with ``"skip"`` **Prerequisites** @@ -64,32 +66,72 @@ With this command, you will execute: - Python 2.7 or newer (2.x) (https://www.python.org/downloads/) - pip (https://pypi.python.org/pypi/pip) - virtualenv (https://pypi.python.org/pypi/virtualenv) -- Monitoring [NGSI-Adapter] (`Download NGSI-Adapter `_) +- NGSI Adapter from FIWARE Monitoring (`download sources`__) + +__ `NGSI Adapter sources`_ **Test case execution using virtualenv** -1. Create a virtual environment somewhere *(virtualenv $WORKON_HOME/venv)* -#. Activate the virtual environment *(source $WORKON_HOME/venv/bin/activate)* -#. Go to *ngsi_adapter/src/test/acceptance* folder in the project -#. Install the requirements for the acceptance tests in the virtual environment *(pip install -r requirements.txt --allow-all-external)* +1. Create a virtual environment somewhere:: + + $ virtualenv $WORKON_HOME/venv + +#. Activate the virtual environment:: + + $ source $WORKON_HOME/venv/bin/activate + +#. Go to the acceptance tests folder in the project:: + + $ cd ngsi_adapter/src/test/acceptance + +#. Install requirements for the acceptance tests in the virtual environment:: + + $ pip install -r requirements.txt --allow-all-external **Test case execution using Vagrant (optional)** -Instead of using virtualenv, you can use the provided Vagrantfile to deploy a local VM using `Vagrant `_, -that will provide all environment configurations for launching test cases. +Instead of using ``virtualenv``, you can use Vagrant_ to deploy a local VM from +the given *Vagrantfile*, providing all environment configurations to launch the +test cases. -1. Download and install Vagrant (https://www.vagrantup.com/downloads.html) -#. Go to *ngsi_adapter/src/test/acceptance* folder in the project -#. Execute *vagrant up* to launch a VM based on Vagrantfile provided. -#. After Vagrant provision, your VM is properly configured to launch acceptance tests. You have to access to the VM using *vagrant ssh* and change to */vagrant* directory that will have mounted your workspace *(test/acceptance)*. +As a prerequisite, first download and install Vagrant +(https://www.vagrantup.com/downloads.html) -If you need more information about how to use Vagrant, you can see -`Vagrant Getting Started `_ +1. Go to the acceptance tests folder in the project:: + + $ cd ngsi_adapter/src/test/acceptance + +#. Launch a VM from the provided *Vagrantfile*:: + + $ vagrant up + +#. After Vagrant provision, your VM is properly configured to launch acceptance + tests. You have to access the VM and change to the Vagrant directory mapping + the *test/acceptance* workspace:: + + $ vagrant ssh + $ cd /vagrant + +For more information about how to use Vagrant, please check `this document`__. + +__ `Vagrant Getting Started`_ **Settings** -Before executing the acceptance tests, you will need configure the properties file. To execute acceptance test on the -experimentation environment, you will have to configured the file *settings/dev-properties*. +Before executing the acceptance tests, you will have configure the properties +file ``settings/dev-properties.json`` and setup the attributes to run the +acceptance tests on the experimentation environment. + +You will also need a valid private key (*private_key_location*) to connect to +NGSI Adapter host to capture remote logs. This way you will be able to execute +scenarios that require the logs capturing for test validations. + + +.. REFERENCES -You will need a valid private key (*private_key_location*) to connect to NGSI-Adapter Host to capture remote logs. -In this way, you will be able to execute Scenarios that require the logs capturing for test validations. +.. _Gherkin: https://github.com/cucumber/cucumber/wiki/Gherkin +.. _Lettuce: http://lettuce.it/ +.. _Python: http://www.python.org/ +.. _Vagrant: https://www.vagrantup.com/ +.. _Vagrant Getting Started: https://docs.vagrantup.com/v2/getting-started/index.html +.. _NGSI Adapter sources: https://github.com/telefonicaid/fiware-monitoring/