Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA Corporation and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA Corporation is strictly prohibited.
#
################################################################################

This project implements protocol adaptor for AMQP.
The adaptor implements and exposed the DSMI API for client applications to interface with it.

Dependencies
-------------

* glib 2.0
----------
 sudo apt-get install libglib2.0 libglib2.0-dev

Install rabbitmq-c library
--------------------------
 git clone -b v0.8.0  --recursive https://github.com/alanxz/rabbitmq-c.git
 mkdir build && cd build
 cmake ..
 cmake --build .
 sudo cp /librabbitmq/librabbitmq.so.4 /opt/nvidia/deepstream/deepstream-<version>/lib/
 sudo ldconfig

If you plan to have AMQP broker installed on your local machine
---------------------------------------------------------------
#Install rabbitmq on your ubuntu system: https://www.rabbitmq.com/install-debian.html
#The “Using rabbitmq.com APT Repository” procedure is known to work well

 sudo apt-get install rabbitmq-server

#Ensure rabbitmq service has started by running (should be the case):
 sudo service rabbitmq-server status

#Otherwise
 sudo service rabbitmq-server start


Specify Connection details
--------------------------
#Make sure to provide all the connection details within cfg_amqp.txt
#The default options are provided in the cfg_amqp.txt which uses hostname=localhost, username=guest, password=guest

OR

#pass in part of the required connection string in the call to nvds_msgapi_connect_ptr:
 conn_handle = msgapi_connect_ptr((char *)"url;port;username",(nvds_msgapi_connect_cb_t) sample_msgapi_connect_cb, (char *)CFG_FILE);
#AND provide the password within cfg_amqp.txt
#password = <password to connect amqp broker>

Specify Amqp Exchange
---------------------
#Default exchange the amqp protocol adapter using is amq.topic
#You can overwrite it by specifying custom amqp exchange name within cfg_amqp.txt
exchange = <custom exchange name>

Specify Topic
-------------
#Default topic is deepstream_topic
#You can overwrite it by specifying custom topic name within cfg_amqp.txt.
topic = <topic_name>
#OR topic per message can be specified as part of the argument to send api. This takes the highest precedence
#ex: NvDsMsgApiErrorType nvds_msgapi_send(NvDsMsgApiHandle h_ptr, char *topic, const uint8_t *msg, size_t nbuf);

Setup and enable logging:
-------------------------
Before running the sample applications, enable logs by running the logger setup script:
For x86,
 chmod u+x ~/deepstream_x86_public/sources/tools/nvds_logger/setup_nvds_logger.sh
 sudo ~/deepstream_x86_public/sources/tools/nvds_logger/setup_nvds_logger.sh
On Jetson,
 chmod u+x ~/deepstream_sdk_on_jetson/sources/tools/nvds_logger/setup_nvds_logger.sh
 sudo ~/deepstream_sdk_on_jetson/sources/tools/nvds_logger/setup_nvds_logger.sh

To run test program:
--------------------
 make -f Makefile.test
 ./test_amqp_proto_async <path_to_libnvds_amqp_proto.so>
 ./test_amqp_proto_sync <path_to_libnvds_amqp_proto.so>

 NOTE:
 libnvds_amqp_proto.so can be found at /opt/nvidia/deepstream/deepstream-<version>/lib/

Limitations:
------------
As stated here at https://github.com/alanxz/rabbitmq-c

You cannot share a socket, an amqp_connection_state_t, or a channel between threads using librabbitmq.
The librabbitmq library is built with event-driven, single-threaded applications in mind, and does not yet cater to any of the requirements of pthreaded applications.

Your applications instead should open an AMQP connection (and an associated socket, of course) per thread.
If your program needs to access an AMQP connection or any of its channels from more than one thread,
it is entirely responsible for designing and implementing an appropriate locking scheme.
It will generally be much simpler to have a connection exclusive to each thread that needs AMQP service.

Test & verify messages published:
--------------------------------

1) Create exchange , queue & and bind queue to exchange:
# Rabbitmq management:
It comes with a command line tool which you can use to create/configure all of your queues/exchanges/etc
https://www.rabbitmq.com/management.html

# Install rabbitmq management plugin:
sudo rabbitmq-plugins enable rabbitmq_management

# Use the default exchange amq.topic
OR create an exchange as below, the same name as the one you specify within the cfg_amqp.txt
#sudo rabbitmqadmin -u guest -p guest -V / declare exchange name=myexchange type=topic

# Create a Queue
sudo rabbitmqadmin -u guest -p guest -V / declare queue name=myqueue durable=false auto_delete=true

#Bind Queue to exchange with routhing_key specification
rabbitmqadmin -u guest -p guest -V / declare binding source=amq.topic destination=myqueue routing_key=topicname

#To check if the queues were actually created, execute:
$ sudo rabbitmqctl list_queues
Listing queues
myqueue      0

2) Consume messages:

#Install the amqp-tools
sudo apt-get install amqp-tools

cat <<EOF > test_amqp_recv.sh
while read -r line; do
    echo "\$line"
done
EOF

chmod +x test_amqp_recv.sh

3) Run the consumer:
amqp-consume  -q "myqueue" -r "topicname" -e "amq.topic" ./test_amqp_recv.sh
