<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [

<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;

]>
<!-- Module User's Guide -->

<chapter xmlns:xi="http://www.w3.org/2001/XInclude">
	<title>&adminguide;</title>


	<section>
		<title>Overview</title>
		<para>The module provides an NSQ consumer for &kamailio; configuration file.
			NSQ is a real time distributed messaging platform, more details about it
			can be found at <ulink url="http://nsq.io">nsq.io</ulink>.
		</para>
		<para>
			From a high-level perspective, the module may be used for:
			<itemizedlist>
				<listitem>
					<para>
						Provide a real-time integration with you &kamailio; configuration file,
						which can be used as alternative to interact with a database, allowing
						to overlay additional logic in your preferred language
						while utilizing a message bus.
					</para>
				</listitem>
				<listitem>
					<para>
						Rely on a distributed messaging layer, such that machines processing
						requests/responses/events can go up/down or share the workload,
						without impacting Kamailio's activity.
					</para>
				</listitem>
			</itemizedlist>
		</para>


		<para>
			Supported NSQ operations are:
			<itemizedlist>
				<listitem>
					<para>
						Subscribe to a Topic and Channel
					</para>
				</listitem>
			</itemizedlist>
		</para>
		<para>
			<emphasis>IMPORTANT</emphasis>
			The `nsq.json` transformation is deprecated in favor of the json module's `json.parse` transformation.
			The `nsq_pua_publish()` function is deprecated in favor of pua_json module's `pua_json_publish()` function.
		</para>

	</section>
	<section>
		<title>How it works</title>
		<para>
			The module creates an additional NSQ manager process that does the communication
			with NSQ for consuming messages. This one defers the message for processing to
			other NSQ worker process so that it doesn't block itself, nor the SIP worker processes.
		</para>
		<section>
			<title>Acknowledge Messages</title>
			<para>
				Consumed messages have the option of being acknowledge in two ways:
				<itemizedlist>
					<listitem>
						<para>
							immediately when received
						</para>
					</listitem>
					<listitem>
						<para>
							after processing by the worker
						</para>
					</listitem>
				</itemizedlist>

			</para>

		</section>
	</section>

	<section>
		<title>Dependencies</title>
		<section>
			<title>&kamailio; Modules</title>
			<para>
				The following modules must be loaded before this module:
				<itemizedlist>
					<listitem>
						<para>
							<emphasis>none</emphasis>.
						</para>
					</listitem>
				</itemizedlist>
			</para>
		</section>
		<section>
			<title>External Libraries or Applications</title>
			<para>
				The following libraries or applications must be installed
				<itemizedlist>
					<listitem>
						<para>
							<emphasis>libev</emphasis>.
						</para>
					</listitem>
					<listitem>
						<para>
							<emphasis>libjson</emphasis>.
						</para>
					</listitem>
					<listitem>
						<para>
							<emphasis>libevbuffsock</emphasis>.
						</para>
					</listitem>
					<listitem>
						<para>
							<emphasis>libnsq</emphasis>.
						</para>
					</listitem>
				</itemizedlist>
			</para>
		</section>
	</section>


	<section>
		<title>Parameters</title>
		<section>
			<title><varname>lookupd_address</varname>(str)</title>
			<para>
				The nsqlookupd address.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is 127.0.0.1</emphasis>
			</para>
			<example>
				<title>Set <varname>lookupd_address</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "lookupd_address", "nsqlookupd.mydomain.com")
...
</programlisting>
			</example>
		</section>
		<section>
			<title><varname>lookupd_port</varname>(int)</title>
			<para>
				The nsqlookupd TCP port.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is 4161.</emphasis>
			</para>
			<example>
				<title>Set <varname>lookupd_port</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "lookupd_port", 4161)
...
				</programlisting>
			</example>
		</section>

		<section>
			<title><varname>nsqd_address</varname>(str)</title>
			<para>
				The nsqd address. You can specify connecting directly to nsqd instead of using nsqlookupd.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is 127.0.0.1</emphasis>
			</para>
			<example>
				<title>Set <varname>nsqd_address</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "nsqd_address", "nsqd.mydomain.com")
...
</programlisting>
			</example>
		</section>
		<section>
			<title><varname>nsqd_port</varname>(int)</title>
			<para>
				The nsqd TCP port.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is 4150.</emphasis>
			</para>
			<example>
				<title>Set <varname>nsqd_port</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "nsqd_port", 4150)
...
</programlisting>
			</example>
		</section>

		<section>
			<title><varname>consumer_use_nsqd</varname>(int)</title>
			<para>
				Set to 1 if you'd like to connect to nsqd instead of nsqlookupd.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is 0.</emphasis>
			</para>
			<example>
				<title>Set <varname>consumer_use_nsqd</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "consumer_use_nsqd", 1)
...
</programlisting>
			</example>
		</section>

		<section>
			<title><varname>consumer_event_key</varname>(str)</title>
			<para>
				The default name of the field in json payload to compose the event name 1st part
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is <quote>Event-Category</quote>.</emphasis>
			</para>
			<example>
				<title>Set <varname>consumer_event_key</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "consumer_event_key", "My-JSON-Field-Name")
...
</programlisting>
			</example>
		</section>

		<section>
			<title><varname>consumer_event_subkey</varname>(str)</title>
			<para>
				The default name of the field in json payload to compose the event name 2nd part
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is <quote>Event-Name</quote>.</emphasis>
			</para>
			<example>
				<title>Set <varname>consumer_event_subkey</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "consumer_event_subkey", "My-JSON-SubField-Name")
...
</programlisting>
			</example>
		</section>

		<section>
			<title><varname>max_in_flight</varname>(int)</title>
			<para>
				The number of messages the consumer can receive before nsqd expects a response.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is 1.</emphasis>
			</para>
			<example>
				<title>Set <varname>max_in_flight</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "max_in_flight", 2)
...
</programlisting>
			</example>
		</section>

		<section>
			<title><varname>consumer_workers</varname>(int)</title>
			<para>
				Number of consumer connections to NSQ per topic_channel.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is 4.</emphasis>
			</para>
			<example>
				<title>Set <varname>consumer_workers</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "consumer_workers", 2)
...
</programlisting>
			</example>
		</section>

		<section>
			<title><varname>topic_channel</varname>(str)</title>
			<para>
				The NSQ Topic and Channel. Delimiter-separated by <quote>:</quote>. It be set multiple times to subscribe to multiple topics and channels. The value of consumer_workers is allocated per topic_channel.
			</para>
			<para>
				Usage: nsq related.
			</para>
			<para>
				<emphasis>Default value is <quote>Kamailio-Topic:Kamailio-Channel</quote>.</emphasis>
			</para>
			<example>
				<title>Set <varname>topic_channel</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("nsq", "topic_channel", "My-NSQ-Topic:My-NSQ-Channel")
modparam("nsq", "topic_channel", "My-NSQ-Topic-2:My-NSQ-Channel-2")
...
				</programlisting>
			</example>
		</section>

	</section>

	<section>
		<title>Pseudo Variables</title>
		<itemizedlist>
			<listitem>
				<para>
					<emphasis>$nsqE</emphasis>
					Contains the payload of a consumed message
				</para>
			</listitem>
			<example>
				<title>Example usage of $nsqE pseudo variable</title>
<programlisting format="linespecific">
	xlog("L_INFO", "received payload $nsqE from NSQ");
	...
}

</programlisting>
			</example>
		</itemizedlist>
	</section>

	<section>
		<title>Event Routes</title>
			<para>
				The worker process issues an event-route where we can act on the received payload. The name of the event-route is composed by values extracted from the payload.
			</para>
			<para>
				NSQ module will try to execute the event route from most significant to less significant.
				define the event route like event_route[nsq:consumer-event[-payload_key_value[-payload_subkey_value]]]
			</para>
			<para>
				We can set the key/subkey pair on a subscription base. check the payload on subscribe.
			</para>
			<example>
				<title>Define the event routes</title>
<programlisting format="linespecific">
...
modparam("nsq", "consumer_event_key", "Event-Category")
modparam("nsq", "consumer_event_subkey", "Event-Name")
...

event_route[nsq:consumer-event-presence-update]
{
	# presence is the value extracted from Event-Category field in json payload
	# update is the value extracted from Event-Name field in json payload
	if ($(nsqE{json.parse,Event-Package}) == "dialog") {
		xlog("L_INFO", "received $(nsqE{json.parse,Event-Package}) update for $(nsqE{json.parse,From})");
		pua_json_publish($nsqE);
	}
	...
}

event_route[nsq:consumer-event-presence]
{
	# presence is the value extracted from Event-Category field in json payload
	xlog("L_INFO", "received $(nsqE{json.parse,Event-Package}) update for $(nsqE{json.parse,From})");
	...
}

event_route[nsq:consumer-event-event-category-event-name]
{
	# event-category is the name of the consumer_event_key parameter
	# event-name is the name of the consumer_event_subkey parameter
	# this event route is executed if we can't find the previous
	...
}

event_route[nsq:consumer-event-event-category]
{
	# event-category is the name of the consumer_event_key parameter
	# this event route is executed if we can't find the previous
	...
}

event_route[nsq:consumer-event]
{
	# this event route is executed if we can't find the previous
}

</programlisting>
			</example>
	</section>


</chapter>

