You may already be familiar with Asterisk, the widely-deployed open-source telephony framework. If you aren't, you should check it out. It's a pretty cool piece of software. A low-load instance of Asterisk can be deployed to use the filesystem to store things like phone-registration data and voicemails. But if you want to do anything fancy with Asterisk, or if you happen to care about things like fault-tolerance, you might look at pointing Asterisk at a database. And if you happen to have a large Asterisk cluster built to handle significant load, you might look at pointing Asterisk at an elastically-scalable database. In this post, I'll walk you through setting up a minimal Asterisk installation on a single RPM-based Linux machine with NuoDB. You can go much farther with Asterisk installs spanning several data centers, but I'll leave those headaches to the experts. Pairing such an installation with NuoDB will at least take the database pain out of such a setup. Let's dive in.
First, download and install NuoDB.
sudo rpm -i nuodb.rpm
This will start a NuoDB broker on this host. Next, we start a Transaction Engine and Storage Manager:
java -jar /opt/nuodb/jar/nuodbmanager.jar --broker localhost --user domain --password bird --command "start process sm database asteriskCDR host localhost archive /tmp/ast-cdr initialize yes" java -jar /opt/nuodb/jar/nuodbmanager.jar --broker localhost --user domain --password bird --command "start process te database asteriskCDR host localhost options '--dba-user asteriskUser --dba-password mySecret'"
Setting up ODBC
While there is native support in Asterisk to talk directly to MySQL and PostgreSQL, the more tested and hardened path is to connect to a database through ODBC. Here, we install unixODBC, the ODBC driver manager implementation for Unix-like operating systems.
as root: yum install gcc gcc-c++ ncurses-devel unixODBC unixODBC-devel
This created two files: /etc/odbc.ini and /etc/odbcinst.ini which we now edit to point at our NuoDB instance.
/etc/odbc.ini [NuoODBC] Description = NuoDB ODBC3 Driver DSN Driver = /opt/nuodb/lib64/libNuoODBC.so Database = asteriskCDR ServerName = localhost User = asteriskUser Password = mySecret Schema = user
We can leave /etc/odbcinst.ini empty, or if you would like to enable (a very verbose!) logging:
/etc/odbcinst.ini [ODBC] TraceFile = /tmp/odbc.log Trace = Yes
These are by no means the only options to get unixODBC up and running, but we'll roll with this for now. Let's make sure that what we've got so far works:
isql NuoODBC asteriskUser mySecret -v -3 +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL>
At the time of writing, the current tested and stable release of Asterisk is 11.4.0, but you can check here for the release of your choice.
as root: yum install libtool-ltdl libtool-ltdl-devel sqlite-devel libxml2-devel openssl-devel libuuid-devel cd /usr/src wget http://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-11.4.0.tar.gz wget http://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-11.4.0.tar.gz.sha1 sha1sum -c asterisk-11.4.0.tar.gz.sha1 tar zxvf asterisk-11.4.0.tar.gz cd asterisk-11.4.0 ./configure --libdir=/usr/lib64 --disable-xmldoc make menuselect && make && make install && make samples && make config
During make menuselect, check the Call Detail Recording (CDR) to make sure that cdr_odbc is enabled. Press q to leave make menuselect. After that, you can get yourself a coffee and spend a few minutes checking out Dinosaur Comics. If compilation on your system succeeded and your distribution is recognized by the make install phase, you should be able to start the Asterisk service:
sudo service asterisk start
Connecting Asterisk and NuoDB
Asterisk can utilize a database in various ways. As an example, we'll set up CDR logging.
/etc/asterisk/cdr_odbc.conf [global] dsn=NuoODBC loguniqueid=no dispositionstring=yes table=cdr usegmtime=yes hrtime=yes /etc/asterisk/res_odbc.conf [NuoODBC] enabled => yes dsn => NuoODBC username => asteriskUser password => mySecret pre-connect => yes sanitysql => select 1 from dual
We force the reload of the configuration files:
sudo service asterisk restart
Now we can check the database connection with a simple command inside the Asterisk console.
asterisk -rvvv <snip> p131*CLI> odbc show ODBC DSN Settings ----------------- Name: NuoODBC DSN: NuoODBC Last connection attempt: 2013-09-03 10:45:41
As you might have guessed, we'll be logging Call Detail Records into a table called cdr. Let's create the table:
/opt/nuodb/bin/nuosql asteriskCDR --user asteriskUser --password mySecret <<EOF CREATE SEQUENCE "SEQ_cdr_cdrID" START WITH 1; CREATE TABLE "cdr" ("cdrID" REAL GENERATED BY DEFAULT AS IDENTITY("SEQ_cdr_cdrID") NOT NULL, "calldate" TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', "clid" VARCHAR(80) NOT NULL DEFAULT '', "src" VARCHAR(80) NOT NULL DEFAULT '', "dst" VARCHAR(80) NOT NULL DEFAULT '', "dcontext" VARCHAR(80) NOT NULL DEFAULT '', "channel" VARCHAR(80) NOT NULL DEFAULT '', "dstchannel" VARCHAR(80) NOT NULL DEFAULT '', "lastapp" VARCHAR(80) NOT NULL DEFAULT '', "lastdata" VARCHAR(80) NOT NULL DEFAULT '', "duration" INTEGER NOT NULL DEFAULT '0', "billsec" INTEGER NOT NULL DEFAULT '0', "disposition" VARCHAR(45) NOT NULL DEFAULT '', "amaflags" INTEGER NOT NULL DEFAULT '0', "accountcode" VARCHAR(20) NOT NULL DEFAULT '', PRIMARY KEY ("cdrID")); CREATE INDEX "IDX_cdr_calldate" ON "cdr" ("calldate"); CREATE INDEX "IDX_cdr_dst" ON "cdr" ("dst"); CREATE INDEX "IDX_cdr_accountcode" ON "cdr" ("accountcode"); EOF
A Simple Test
To show that this all works, we'll add a few lines of Dialplan to the bottom of /etc/asterisk/extensions.confand test the setup with SIPp.
/etc/asterisk/extensions.conf [sipp] exten => 123,1,Answer exten => 123,2,SetMusicOnHold(default) exten => 123,3,WaitMusicOnHold(2) exten => 123,4,Hangup /etc/asterisk/sip.conf [sipp] type=friend context=sipp host=dynamic user=sipp canreinvite=no disallow=all allow=ulaw
We force the reload of the configuration files again, and install SIPp:
as root: service asterisk restart yum install sipp
If your distribution's repositories don't contain SIPp, it's only a simple make away. To test our installation, we run the following command. You can verify that SIPp is pointed at your Asterisk instance by seeing the logs in the Asterisk console.
sipp -d 2000 -s 123 127.0.0.1 -l 10 -timeout 4s
Now we can confirm that we got call logs by seeing a non-zero number after issuing:
echo "select count(*) from cdr;" | /opt/nuodb/bin/nuosql asteriskCDR --user asteriskUser --password mySecret
Since Asterisk is a framework that can run a wide variety of telephony applications, there are arbitrarily-many possible connection points between it and a database. We've tested the CDR functionality, and a few other paths, but we'd love your feedback. Please let us know about your experiences using Asterisk and NuoDB!