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

<chapter>
	
	<title>&adminguide;</title>
	
	<section id="overview" xreflabel="Overview">
	<title>Overview</title>
	<para>
		This module is an implementation of a cache system designed to work with
		MongoDB servers.
		It implements the Key-Value interface exposed by the OpenSIPS core.
	</para>
	<para>
		The underlying client library is compatible with any of the following
		MongoDB server versions: 2.4, 2.6, 3.0, 3.2 and 3.4, as stated in 
		<ulink url="https://docs.mongodb.com/ecosystem/drivers/driver-compatibility-reference/">
			the MongoDB documentation</ulink>.
	</para>
	<para>
	</para>
	</section>

	<section>
	<title>Advantages</title>
	<para>
		<itemizedlist>
			<listitem>
			<para>
				<emphasis>memory costs are no longer on the server
				</emphasis>
			</para>
			</listitem>

			<listitem>
			<para>
				<emphasis>many servers can be used inside a cluster, so the memory
				is virtually unlimited</emphasis>
			</para>
			</listitem>

			<listitem>
			<para>
				<emphasis>the cache is 100% persistent. A restart
					of OpenSIPS server will not affect the DB. The MongoDB is also
				persistent so it can also be restarted without loss of information.</emphasis>
			</para>
			</listitem>

			<listitem>
			<para>
				<emphasis>MongoDB is an open-source project so
				it can be used to exchange data
				 with various other applications</emphasis>
			</para>
			</listitem>

			<listitem>
			<para>
				<emphasis>By creating a MongoDB Cluster, multiple OpenSIPS
				instances can easily share key-value information</emphasis>
			</para>
			</listitem>

			<listitem>
			<para>
				<emphasis>This module also implements the CacheDB Raw query
				capability, thus you can run whatever query that the MongoDB
				back-end supports, taking full advatange of it.
				</emphasis>
			</para>
			</listitem>

		</itemizedlist>
	</para>
	<para>
	</para>
	</section>

	<section>
	<title>Limitations</title>
	
		
		<para>
			<itemizedlist>
			<listitem>
			<para>
			<emphasis>
		keys (in key:value pairs) may not contain spaces or control characters
		</emphasis>
			</para>
			</listitem>

		</itemizedlist>
		</para>
	</section>

	<section id="dependencies" xreflabel="Dependencies">
	<title>Dependencies</title>
	<section>
		<title>&osips; Modules</title>
		<para>
		None.
		</para>
	</section>
	
	<section>
		<title>External Libraries or Applications</title>
		<para>
		The following packages must be installed before running &osips; with this module loaded:
		</para>
		<para>
		<example>
			<title>Runtime requirements for "cachedb_mongodb"</title>
				<programlisting format="linespecific">
# Debian / Ubuntu
sudo apt-get install libjson-c2 libmongoc-1.0

# Red Hat / CentOS
sudo yum install json-c mongo-c-driver
				</programlisting>
			</example>
		</para>

		<para>
		The following packages are required in order to compile this module:
		</para>
		<para>
		<example>
			<title>Compilation requirements for "cachedb_mongodb"</title>
				<programlisting format="linespecific">
# Debian / Ubuntu
sudo apt-get install libjson-c-dev libmongoc-dev libbson-dev

# Red Hat / CentOS
sudo yum install json-c-devel mongo-c-driver-devel
				</programlisting>
			</example>
		</para>

	</section>
	</section>

	<section id="exported_parameters" xreflabel="Exported Parameters">
		<title>Exported Parameters</title>
		<section id="param_cachedb_url" xreflabel="cachedb_url">
		<title><varname>cachedb_url</varname> (string)</title>
		<para>
			The URLs of the server groups that OpenSIPS will connect to in order
			to allow the cache_store(), cache_fetch(), etc. functions to be used
			from the OpenSIPS script. It can be set more than one time.
			The prefix part of the URL will be the identifier that will be used
			from the script.
		</para>

		<para>
			The URL syntax is identical to the one used by MongoDB, including
			connect string options. For more info,
			please refer to <ulink url="https://docs.mongodb.com/manual/reference/connection-string/">
				the official MongoDB connect string documentation</ulink>.
		</para>

		<example>
		<title>Set <varname>cachedb_url</varname> parameter</title>
		<programlisting format="linespecific">
...
# Connect to a single <emphasis>mongod</emphasis> instance
modparam("cachedb_mongodb", "cachedb_url",
         "mongodb://localhost:27017/opensipsDB.dialog")

# Connect to a <emphasis>mongod</emphasis> replica set
modparam("cachedb_mongodb", "cachedb_url",
         "mongodb://10.0.0.10,10.0.0.11:27017/opensipsDB.dialog?replicaSet=my-set")

# Connect to a <emphasis>mongos</emphasis> instance (routes to a sharded cluster)
modparam("cachedb_mongodb", "cachedb_url",
         "mongodb://localhost/opensipsDB.dialog")

# Example of multiple connections:
#   * to a main <emphasis>mongos</emphasis>, with failover to a backup <emphasis>mongos</emphasis>
#   * to a single <emphasis>mongod</emphasis>
modparam("cachedb_mongodb", "cachedb_url",
         "mongodb:cluster://localhost,10.0.0.10:27017/opensipsDB.dialog")
modparam("cachedb_mongodb", "cachedb_url",
         "mongodb://localhost:27017/opensipsDB.userlocation")
...
	</programlisting>
		</example>

		<example>
		<title>Reference MongoDB connections</title>
		<programlisting format="linespecific">
...
cache_store("mongodb", "key", "$ru value");
cache_remove("mongodb:cluster", "key");
cache_fetch("mongodb:instance1", "key", $avp(10));
...
	</programlisting>
		</example>
	</section>

		<section id="param_exec_threshold" xreflabel="exec_threshold">
		<title><varname>exec_threshold</varname> (int)</title>
		<para>
			The maximum number of microseconds that a mongodb query can last.
			Anything above the threshold will trigger a warning message to the log
		</para>
		<para>
		<emphasis>Default value is <quote>0 ( unlimited - no warnings )</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>exec_threshold</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("cachedb_mongodb", "exec_threshold", 100000)
...
	</programlisting>
		</example>
	</section>

		<section id="param_compat_mode_2.4" xreflabel="compat_mode_2.4">
		<title><varname>compat_mode_2.4</varname> (int)</title>
		<para>
			Switch the module into compatibility mode for MongoDB 2.4 servers.
			Specifically, this allows "insert/update/delete" raw queries to not fail,
			since they were introduced in MongoDB 2.6. The module will interpret
			the raw query JSON, convert it to its corresponding command and run it.
		</para>
		<para>
			Caveat: only the minimally required raw query options are
			supported in this mode.
		</para>
		<para>
		<emphasis>Default value is <quote>0 (disabled)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting the <varname>compat_mode_2.4</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("cachedb_mongodb", "compat_mode_2.4", 1)
...
	</programlisting>
		</example>
	</section>

		<section id="param_compat_mode_3.0" xreflabel="compat_mode_3.0">
		<title><varname>compat_mode_3.0</varname> (int)</title>
		<para>
			Switch the module into compatibility mode for MongoDB 2.6/3.0 servers.
			Specifically, this allows "find" raw queries to not fail,
			since they were introduced in MongoDB 3.2. The module will interpret
			the "find" raw query JSON, convert it to its corresponding command and run it.
		</para>
		<para>
			Caveat: only the minimally required options for "find" raw queries are
			supported in this mode.
		</para>
		<para>
		<emphasis>Default value is <quote>0 (disabled)</quote>.
		</emphasis>
		</para>
		<example>
		<title>Setting the <varname>compat_mode_3.0</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("cachedb_mongodb", "compat_mode_3.0", 1)
...
	</programlisting>
		</example>
	</section>

</section>

	<section id="exported_functions" xreflabel="exported_functions">
		<title>Exported Functions</title>
		<para>The module does not export functions to be used
		in configuration script.</para>
	</section>	


	<section>
	<title>Raw Query Syntax</title>
		<para>
			The cachedb_mongodb module supports raw queries, thus taking
			full advantage of the capabilities of the back-end, including
			query-specific options such as read/write preference, timeouts,
			filtering options, etc.
		</para>
		<para>
			The query syntax is identical to the mongo cli. Documentation for it
			can be found on the
			<ulink url="https://docs.mongodb.com/manual/reference/command/nav-crud/">
				MongoDB website</ulink>. Query results
			are returned as JSON documents, that one can further process
			in the OpenSIPS script by using the JSON module.
		</para>

		<para>
			Some example raw queries:
			<example>
			<title>MongoDB Raw Insert</title>
			<programlisting format="linespecific">
...
cache_raw_query("mongodb:cluster", "{ \
    \"insert\": \"ip_blacklist\", \
    \"documents\": [{ \
        \"username\": \"$fU\", \
        \"ip\": \"$si\", \
        \"attempts\": 1 \
     }]}",
 "$avp(out)");
xlog("INSERT RAW QUERY returned $rc, output: '$avp(out)'\n");
...
			</programlisting>
			</example>

			<example>
			<title>MongoDB Raw Update</title>
			<programlisting format="linespecific">
...
cache_raw_query("mongodb:cluster", "{ \
    \"update\": \"ip_blacklist\", \
    \"updates\": [{ \
        \"q\": { \
            \"username\": \"$fU\", \
            \"ip\": \"$si\" \
         }, \
        \"u\": { \
            \"$$inc\": {\"attempts\": 1} \
         } \
      }]}",
 "$avp(out)");
xlog("UPDATE RAW QUERY returned $rc, output: '$avp(out)'\n");
...
			</programlisting>
			</example>
		</para>

	</section>

</chapter>

