Using Realtime

The Asterisk Realtime Architecture (ARA) is a method of storing the configuration files (that would normally be found in /etc/asterisk) and their configuration options in a database table. There are two types of realtime; static and dynamic. The static version is similar to the traditional method of reading a configuration file, except that the data is read from the database instead. The dynamic realtime method is used for things such as user and peer objects (SIP, IAX2), and voicemail which loads and updates the information as it is required. Changes to static information requires a reload just as if you had changed the text file on the system, but dynamic information is polled by Asterisk as needed and requires no reload. Realtime is configured in the extconfig.conf file located in the /etc/asterisk directory. This file tells Asterisk what to load from the database and where to load it from, allowing certain files to be loaded from the database and other files to be loaded from the standard configuration files.

Static Realtime

Static realtime is used when you want to store the configuration that you would normally place in the configuration files in /etc/asterisk but want to load from a database. The same rules that apply to flat files on your system still apply when using static realtime, such as requiring you to either run the reload command from the Asterisk CLI, or to reload the module associated with the configuration file (i.e., module reload chan_sip.so).

When using static realtime, we tell Asterisk which files we want to load from the database using the following syntax in the extconfig.conf file:

; /etc/asterisk/extconfig.conf
filename.conf => driver,database[,table]

Note

If the table name is not specified, then Asterisk will use the name of the file instead.

The static realtime module uses a specifically formatted table to read the configuration of static files in from the database. You can define the table for static realtime in PostgreSQL as follows:

CREATE TABLE ast_config
(
  id serial NOT NULL,
  cat_metric int4 NOT NULL DEFAULT 0,
  var_metric int4 NOT NULL DEFAULT 0,
  filename varchar(128) NOT NULL DEFAULT ''::character varying,
  category varchar(128) NOT NULL DEFAULT 'default'::character varying,
  var_name varchar(128) NOT NULL DEFAULT ''::character varying,
  var_val varchar(128) NOT NULL DEFAULT ''::character varying,
  commented int2 NOT NULL DEFAULT 0,
  CONSTRAINT ast_config_id_pk PRIMARY KEY (id)
) 
WITHOUT OIDS;

A brief explanation about the columns is required in order to understand how Asterisk takes the rows from the database and applies them to the configuration for the various modules you may load:

cat_metric

The weight of the category within the file. A lower metric means it appears higher in the file (see the sidebar A Word About Metrics”).

var_metric

The weight of an item within a category. A lower metric means it appears higher in the list. This is useful for things like codec order in sip.conf or iax.conf where you want disallow=all to appear first (metric of 0), followed by allow=ulaw (metric of 1), then by allow=gsm (metric of 2) (see the sidebar A Word About Metrics”).

filename

The filename the module would normally read from the hard drive of your system (i.e., musiconhold.conf, sip.conf, iax.conf, etc.).

category

The section name within the file, such as [general], but don’t save to the database using the square brackets.

var_name

The option on the left side of the equals sign (i.e., disallow is the var_name in disallow=all).

var_val

The value to an option on the right side of the equals sign (i.e., all is the var_val in disallow=all).

commented

Any value other than 0 will evaluate as if it were prefixed with a semicolon in the flat file (commented out).

A simple file we can load from static realtime is the musiconhold.conf file. Let’s start by moving this file to a temporary location:

# cd /etc/asterisk
# mv musiconhold.conf musiconhold.conf.old

In order for the classes to be removed from memory, we need to restart Asterisk. Then we can verify our classes are blank by running moh show classes:

*CLI> restart now
*CLI> moh show classes
*CLI>

So let’s put the [default] class back into Asterisk, but now we’ll load it from the database. Connect to PostgreSQL and execute the following INSERT statements:

INSERT INTO ast_config (filename,category,var_name,var_val) 
VALUES ('musiconhold.conf','general','mode','files');
INSERT INTO ast_config (filename,category,var_name,var_val) 
VALUES ('musiconhold.conf','general','directory','/var/lib/asterisk/moh');

You can verify your values have made it into the database by running a SELECT statement:

asterisk=# select filename,category,var_name,var_val from ast_config;

 filename         | category       | var_name     | var_val                  
------------------+----------------+--------------+------------------------
 musiconhold.conf | general        | mode         | files
 musiconhold.conf | general        | directory    | /var/lib/asterisk/moh
(2 rows)

And now, there’s just one last thing to modify in the extconfig.conf file in /etc/asterisk directory to tell Asterisk to get the data for musiconhold.conf from the database. Add the following line to the end of the extconfig.conf file, then save it:

musiconhold.conf => odbc,asterisk,ast_config

Then connect to the Asterisk console and perform a reload:

*CLI> module reload

You can now verify that we have our music-on-hold classes loading from the database by running moh show classes:

*CLI> moh show classes
Class: general
        Mode: files
        Directory: /var/lib/asterisk/moh

And there you go; musiconhold.conf loaded from the database. You can perform the same steps in order to load other flat files from the database!

Dynamic Realtime

The dynamic realtime system is used to load objects that may change often: SIP/IAX2 users and peers, queues and their members, and voicemail. Since this information in the system may either be changing or new records are being added on a regular basis, we can utilize the power of the database to let us load this information on an as-needed basis.

All of realtime is configured in the /etc/asterisk/extconfig.conf file, but dynamic realtime has well-defined configuration names such as sippeers. Defining something like SIP peers is done with the following format:

; extconfig.conf
sippeers => driver,database[,table]

The table name is optional, in which case Asterisk will use the predefined name (i.e., sippeers) as the table to look up the data. In our example, we’ll be using the ast_sippeers table to store our SIP peer information.

Tip

Remember that we have both SIP peers and SIP users; peers are end-points we send calls to, and a user is something we receive calls from. A friend is shorthand that defines both.

So to configure Asterisk to load all SIP peers from a database using realtime, we would define something like:

; extconfig.conf
sippeers => odbc,asterisk,ast_sipfriends

To also load our SIP users from the database, define it like so:

sipusers => odbc,asterisk,ast_sipfriends

You may have noticed we used the same table for both the sippeers and sipusers. This is because there will be a type field (just as if you had defined the type in the sip.conf file) that will let us define a type of user, peer, or friend. When defining the table for SIP users and peers, we need at least the following:

+------+--------+-------+--------+-----+------------+----------+
|name  |host    |secret | ipaddr | port| regseconds | username |
+------+--------+-------+--------+-----+------------+----------+
|100   |dynamic |welcome|        |     |1096954152  |   1000   |
+------+--------+-------+--------+-----+------------+----------+

The port, regseconds, and ipaddr fields are required to let Asterisk store the registration information for the peer in order to know where to send the call. This is assuming the host is dynamic; however, if the peer is static, we would have to populate the ipaddr field ourselves. The port field is optional and would use the default standard port defined in the [general] section, and the regseconds would remain blank.) There are many more options for a SIP friend that we can define, such as the caller ID, and adding that information is as simple as adding the callerid column to the table. See the sip.conf.sample file for more options that can be defined for SIP friends.