viernes, 30 de abril de 2010

Installing the Asterisk Test Suite

Ayer en el blog oficial de asterisk postearon un artículo interesante acerca de la test suite de asterisk, les recomiendo leer el archivo README que tiene para ver de que se trata la idea, esta muy interesante espero poderlo empezar a probar en mi maquina virtual, saludos. Aquí va el post:

The Asterisk Test Suite is a way of developing external tests to Asterisk in order to test for functionality differences between different versions of Asterisk. By creating automated tests you are able to verify functionality you depend on remains undisturbed by changes in the code base. Tests you write can even be submitted back to the Asterisk project in order for them to be included directly in the test suite where the automated testing framework can execute the tests so developers will be alerted if a change they make causes a test to fail.

In order to write these tests we need to be able to run the test suite on our development machine (typically a virtual machine or some other box which you won’t be using for production). We’ll be installing the test suite on an Ubuntu Server 9.10 along with the dependencies, then running the automated tests. Writing automated tests though is beyond the scope of this document. See the README.txt file in the testsuite/ directory for more information (http://svn.asterisk.org/svn/testsuite/asterisk/trunk/README.txt).

We’ll be starting with a fresh, minimal install of Ubuntu Server 9.10, so once you’ve gotten that installed, feel free to move on.

Installing Dependencies


Before we get started building the test suite, we need to install the dependencies it requires. The following applications are necessary to run all the currently developed tests, but additional dependencies surely will be required in the future. The current list of dependencies is available in the README.txt file within the testsuite/ repository (referenced earlier). Don’t worry about installing all these dependencies now, because we’re going to step through all the applications you need to install throughout the post.

  • SIPp

  • python >= 2.4

  • python-yaml

  • bash

  • asttest

  • StarPy

  • python-twisted


Building Asterisk and the Test Suite


The Asterisk Test Suite must be installed and run as root, so if you’re not root, switch now (sudo su -) and we’ll get started!

First thing we want to do is create our directory structure and then checkout the version of Asterisk we want to test, and then grab the test suite. If you haven’t already installed Subversion, then do that now (apt-get install subversion).
# cd /usr/src/
# mkdir asterisk-complete
# cd asterisk-complete
# mkdir asterisk
# cd asterisk
# svn co http://svn.asterisk.org/svn/asterisk/branches/1.6.2 1.6.2-vanilla
# cd 1.6.2-vanilla
# svn co http://svn.asterisk.org/svn/testsuite/asterisk/trunk testsuite

Notice that we checked out the latest 1.6.2 branch and named it 1.6.2-vanilla. We then changed into the 1.6.2-vanilla directory and checked out the test suite. This is because the scripts being run from the test suite expect to be located in a subdirectory of Asterisk.

The test suite expects Asterisk to already be installed the first time it runs, so we should make sure we can compile Asterisk. We can find the bare dependencies we need with the./configure script and install those one at a time as it fails to find the necessary components for compiling.

Note: Of course you don’t have to run ./configure multiple times — you could just install all the necessary dependencies by running: apt-get install gcc g++ libxml2-dev





# pwd
/usr/src/asterisk-complete/asterisk/1.6.2-vanilla
# ./configure
configure: error: no acceptable C compiler found in $PATH

So we have our first dependency to resolve. In this case we’re missing the GCC compiler, so lets install that now with: apt-get install gcc. Several package dependencies will be listed. Press Y to continue with the installation of GCC and its dependencies.

Now that we have our GCC compiler installed lets see what our next dependency is.
# ./configure
configure: error: C++ preprocessor "/lib/cpp" fails sanity check

We’re missing the GCC C++ preprocessor, which can be installed by running: apt-get install g++. You will see several dependencies listed and they can all be installed by pressing Y.

If we run ./configure again we appear to get much closer, but not quite all the way.
# ./configure
checking for xml2-config... no
configure: *** XML documentation will not be available because the 'libxml2' development package is missing.
configure: *** Please run the 'configure' script with the '--disable-xmldoc' parameter option
configure: *** or install the 'libxml2' development package.

Appears we’re missing the development libraries for the XML documentation. Lets install that now with: apt-get install libxml2-dev. A couple of dependencies will be installed along with libxml2-dev after pressing Y.
# ./configure
configure: error: *** termcap support not found (on modern systems, this typically means the ncurses development package is missing)

Lets install the missing ncurses-dev package and dependencies with: apt-get install ncurses-dev
# ./configure
configure: Package configured for:
configure: OS type  : linux-gnu
configure: Host CPU : i686
configure: build-cpu:vendor:os: i686 : pc : linux-gnu :
configure: host-cpu:vendor:os: i686 : pc : linux-gnu :

That’s it! If you see the big Asterisk symbol in ASCII text then you’ve made it to the end. Of course this is the bare minimum to get Asterisk compiled and installed, but we’ll use this for now. We’ll likely need to install some additional packages later to meet the dependencies of the test suite.

Lets try running the runtests.py script found in the testsuite/ subdirectory located in our Asterisk source. Remember that we checked this out earlier and is not part of the standard Asterisk checkout.
# cd testsuite/
# ./runtests.py
Traceback (most recent call last):
File "./runtests.py", line 15, in <module>
import yaml
ImportError: No module named yaml

OK, so we’re missing the python yaml package. We can install this with: apt-get install python-yaml

If we run the runtests.py script again we’ll get the following error:
# ./runtests.py
I/O Error getting Asterisk version from ../include/asterisk/version.h

This means we didn’t compile and install Asterisk prior to running our tests! So before continuing with our test suite install, we need to install Asterisk.
# cd ..
# pwd
/usr/src/asterisk-complete/asterisk/1.6.2-vanilla
# make install

Now that we have installed Asterisk, lets see where that gets us with our runtests.pyscript. We’re going to pass it the -l flag in order to list the tests we could potentially run, and the status of the dependencies they require.
# cd testsuite/
# ./runtests.py -l
Configured tests:
001) example
--> Summary: Check to see if the Asterisk binary has been installed
--> Minimum Version: 1.4 (True)
--> Dependency: bash -- Met: True
002) ami-login
--> Summary: Test loggin in to the Asterisk Manager Interface
--> Minimum Version: 1.4 (True)
--> Dependency: twisted -- Met: True
--> Dependency: starpy -- Met: False
003) blind-transfer-accountcode
--> Summary: Test account code propagation for SIP blind transfers.
--> Minimum Version: 1.4 (True)
--> Dependency: bash -- Met: True
--> Dependency: sipp -- Met: False
--> Dependency: asttest -- Met: False
004) rfc2833_dtmf_detect
--> Summary: Test RFC2833 DTMF detection
--> Minimum Version: 1.4 (True)
--> Dependency: bash -- Met: True
--> Dependency: sipp -- Met: False
--> Dependency: asttest -- Met: False
005) sip_channel_params
--> Summary: Test Retrieval of SIP CHANNEL parameters
--> Minimum Version: 1.8 (False)
--> Dependency: bash -- Met: True
--> Dependency: sipp -- Met: False
--> Dependency: asttest -- Met: False
006) iax-call-basic
--> Summary: Test a basic IAX2 call
--> Minimum Version: 1.4 (True)
--> Dependency: twisted -- Met: True
--> Dependency: starpy -- Met: False
007) manager-action-events-response
--> Summary: Test the presence and absence of a response from the Events manager action
--> Minimum Version: 1.4 (True)
--> Dependency: bash -- Met: True
--> Dependency: asttest -- Met: False
008) originate-cdr-disposition
--> Summary: Test for proper CDR dispositions when originating calls.
--> Minimum Version: 1.4 (True)
--> Dependency: bash -- Met: True
--> Dependency: sipp -- Met: False
--> Dependency: asttest -- Met: False
009) func_srv
--> Summary: Test func_srv for correctness
--> Minimum Version: 1.8 (False)
--> Dependency: asttest -- Met: False
010) sip_outbound_address
--> Summary: Test explicit outbound host for SIP calls
--> Minimum Version: 1.4 (True)
--> Dependency: bash -- Met: True
--> Dependency: sipp -- Met: False
--> Dependency: asttest -- Met: False

There will likely be more by the time you try this out, but I think that’s a pretty good sampling. Looking through the tests we can see several dependencies being met with True and several others being met with False. Our goal now is to make sure we satisfy all the dependencies for the tests prior to running them. Starting at the top, the first dependency we haven’t satisfied is starpy.

From the StarPy website at http://www.vrplumber.com/programming/starpy/, “StarPy is a Python + Twisted protocol that provides access to the Asterisk PBX’s Manager Interface (AMI) and Fast Asterisk Gateway Interface (FastAGI). Together these allow you write both command-and-control interfaces (used, for example to generate new calls) and to customise user interactions from the dial-plan.  You can readily write applications that use the AMI and FastAGI protocol together with any of the already-available Twisted protocols“. Basically some tests are using it to generate calls in Asterisk to perform various tests.

We can install StarPy with the following commands:
# cd /usr/src/asterisk-complete/
# mkdir thirdparty
# cd thirdparty
# svn co https://starpy.svn.sourceforge.net/svnroot/starpy
# cd starpy/trunk/
# python setup.py install

You can see that we created a thirdparty/ directory within our asterisk-complete/directory and checked out the latest version of StarPy. We then installed it via the setup.pyscript, and that’s it for satisfying the StarPy dependency.

After we change back to our testsuite/starpy dependency is satisfied:
# cd /usr/src/asterisk-complete/asterisk/1.6.2-vanilla/testsuite/
# ./runtests.py -l
...
--> Dependency: starpy -- Met: True
...

Let’s look and see what our next dependency is. Scrolling down a bit we can see the following:
--> Dependency: sipp -- Met: False

We need to install SIPp which is used for generating calls into the system. SIPp is a very useful utility for load testing Asterisk and executing detailed call flows. More information about SIPp is available at http://sipp.sourceforge.net/. We must install SIPp from source because some of the tests are already using advanced functionality for testing things like DTMF, so wecan’t use the precompiled sip-tester package.

Note: Be sure to grab the latest SIPp snapshot. Right now that is version 2009-07-29.


# cd /usr/src/asterisk-complete/thirdparty
# mkdir sipp
# cd sipp
# wget http://sipp.sourceforge.net/snapshots/sipp.2009-07-29.tar.gz
# tar zxvf sipp.2009-07-29.tar.gz
# cd sipp.svn
# make pcapplay
send_packets.c:44:18: error: pcap.h: No such file or directory
make[1]: *** [send_packets.o] Error 1
make[1]: Leaving directory `/usr/src/asterisk-complete/thirdparty/sipp/sipp.svn'
make: *** [pcapplay] Error 2

Uh oh! We’re missing pcap support! Lets install that now.
# apt-get install libpcap-dev

Now we can compile SIPp with pcap support. There is no ‘make install‘ target to run, so we can just copy the resulting sipp binary to /usr/bin (or some other appropriate location that exists in your path).
# make pcapplay
# cp sipp /usr/bin
# cd /usr/src/asterisk-complete/asterisk/1.6.2-vanilla/testsuite/

After verifying that the SIPp dependency is available, we notice the next one in our list is asttest.
--> Dependency: asttest -- Met: False

The asttest dependency is an application distributed as part of the Asterisk test suite. It is dependent on Lua and the Lua development libraries. Switching in to the asttest/ directory and running ‘make‘ will provide the following error:
# cd asttest/
# pwd
/usr/src/asterisk-complete/asterisk/1.6.2-vanilla/testsuite/asttest
# make
make[1]: *** [src/lfs.o] Error 1
make[1]: Leaving directory `/usr/src/asterisk-complete/asterisk/1.6.2-vanilla/testsuite/asttest/lib/lua/luafilesystem-1.4.2'
make: *** [lib/lua/luafilesystem-1.4.2/src/lfs.o] Error 2

We can install the Lua development libraries and dependencies by running: apt-get install liblua5.1-0-dev lua5.1
# apt-get install liblua5.1-0-dev lua5.1

After installing Lua, we can run ‘make install‘ to install asttest.

At this point if you run ./runtests -l you will notice that all the dependencies have been satisfied (unless of course new tests have been added which require additional dependencies not yet required). So go ahead and run the tests and see if your checkout of Asterisk will pass all the tests!
# cd ..
# pwd
/usr/src/asterisk-complete/asterisk/1.6.2-vanilla/testsuite
# ./runtests.py

Once all the tests have completed, you’ll be provided a summary of the test that were run and their pass/fail status. The last part of the output will also be some XML output that you could use in scripts.
=== TEST RESULTS ===
--> example --- PASSED
--> ami-login --- PASSED
--> blind-transfer-accountcode --- PASSED
--> rfc2833_dtmf_detect --- PASSED
--> iax-call-basic --- PASSED
--> manager-action-events-response --- PASSED
--> originate-cdr-disposition --- PASSED

<?xml version="1.0" encoding="UTF-8"?>
<testsuite errors="0" time="158.71" tests="10" name="AsteriskTestSuite">
<testcase time="0.01" name="example"/>
<testcase time="25.51" name="ami-login"/>
<testcase time="12.24" name="blind-transfer-accountcode"/>
<testcase time="12.05" name="rfc2833_dtmf_detect"/>
<testcase time="20.35" name="iax-call-basic"/>
<testcase time="67.09" name="manager-action-events-response"/>
<testcase time="21.48" name="originate-cdr-disposition"/>
</testsuite>

As you can see, all 10 of our tests passed and took 158 seconds to execute. Now that you have the test suite infrastructure setup and executing all the tests, you can start building your own tests. More information about buildings tests is available in the README.txt file within the top level of your testsuite/ directory. Go forth and create tests!

Lo que traerá Asterisk 1.8

Elio Rojano nos trae un artículo con algunas mejoras que traerá Asterisk 1.8, les recuerdo que esta planeada su salida para el segundo trimestre del 2010.

Estos días en los que la publicación de Asterisk 1.8 está tan cerca, hemos empezado a comentar algunas novedades con respecto a qué es Asterisk 1.8, y algunas de las características que se han hecho públicas en distintos medios de Internet.



Esta versión es quizá más esperada de lo que la mayoría de usuarios creen y aunque las distribuciones enlatadas están empezando a plantearse Asterisk 1.6, es un movimiento complicado ya que en cuanto aparezca Asterisk 1.8 va a traer tantas modificaciones que para el usuario final que no haya trabajado antes con Asterisk 1.6, le va a resultar especialmente complicado adaptarse a esta nueva versión.

No obstante, hemos hecho una recopilación de las principales novedades y las hemos reunido en este artículo para que cualquiera que esté interesado en adentrarse en esta nueva versión y que conozca bien las anteriores versiones, pueda darse cuenta de lo que va a tener que aprender si va a querer aprovechar al máximo las características de esta nueva versión.

Por supuesto, los cambios son principalmente internos a nivel de desarrollo, aunque me ha llamado la atención algunas de las novedades que Kevin P. Flemming anunció que está planteado incluir en Asterisk 1.8 que como mínimo son impresionantes…

Vamos a verlas…

  • Soporte para el tan esperado “cifrado del audio” mediante SRTP será añadido finalmente al chan_sip.

  • Soporte para PacketCable NCS 1.0 para redes Docsis/Eurodocsis en MGCP del que ya anunciamos el desarrollo.

  • Añadidas nuevas opciones para el modulo chan_spy:

    • Añadida opción c() para permitir DTMF para seleccionar el próximo canal disponible a escuchar. Por defecto actualmente es ‘*’.

    • Añadida la opción x() para salir de la aplicación al pulsar una tecla.

    • Añadida la opción S para salir de la aplicación cuando no haya más canales a los que poder escuchar.

    • Añadida la opción E para escuchar un canal y salir de la aplicación cuando este canal finalice.



  • La aplicación Meetme dispone de una función DENOISE() que elimina el ruido de fondo y obtiene sonido más límpio.

  • Soporte para el nuevo interfaz CEL (Channel Event Logging), se introduce oficialmente aquí. CEL loguea todos los eventos tal y como lo hace el AMI, pero CEL está más orientado a lo que hace el CDR.

  • Soporte de integración con calendarios. Nuevas aplicaciones permitirán obtener fechas y ejecutar acciones cuando ocurran eventos programados en el calendario.

  • El nuevo motor RTP permitirá Multicast, ideal para cuando trabajamos con altavoces que escuchan este tipo de paquetes y queremos lanzar avisos.

  • Para el app_queue, ahora se puede especificar la posición en la que un llamante ingresa en la cola y así poder dar prioridades a ciertas personas que entren en la cola.

  • Soporte para actualizar dinámicamente la información de una llamada. Esto permitirá cambiar parámetros como el CallerID durante una llamada, ideal para cuando hacemos una transferencia o un desvío.

  • Añadida una nueva característica llamada “call completion” o “informe de llamada” que permite a un usuario informar a otro que está disponible cuando deje de estar ocupado.

  • Mejora del soporte de faxes que ya comentamos en este post.

  • Soporte nativo para IPV6 (por fín!).


Además de todas las novedades de las últimas versiones de Asterisk 1.6 (que no son pocas).

Aunque quizá lo más interesante de esta nueva versión, es la forma en la que se desarrolla, el esperado LTS (Long Term Support) y que viene a ser que durante varios años se mantendrá y funcionará una única rama: Asterisk 1.8y las modificaciones y correcciones se harán siempre en la misma rama de forma que tanto los desarrolladores como los usuarios se centrarán en mejorar esta única versión, por lo que se espera que esta versión sea además de la más completa, la más estable de las actuales (incluso más estable que la 1.4) ya que durante el desarrollo de las últimas versiones de la 1.4, muchos desarrolladores empezaron modificar la nueva versión 1.6 y por esto, dejaron de lado a la rama más estable y se centraron en las nuevas características que hay actualmente

miércoles, 28 de abril de 2010

Asterisk y la replicación MySQL Master-Master en CentOS

Hoy veremos como utilizar la replicación MySQL Master-Master para la misma base de datos pero solamente para la tabla CDR. Que diferencia hay entra una replicación Maestro-Esclavo y una Maestro-Maestro?

En el primer caso tenemos una copia de todos los registros en otro servidor y podemos efectuar estadísticas usando el Esclavo sin sobrecargar el Maestro. En el segundo caso la configuración se utiliza para la alta disponibilidad en Asterisk. Dos servidores asterisk: A y B. Si A se cae B toma su lugar. Cuando A vuelve a funcionar, B vuelve a ser el servidor de respaldo. Como veremos en un próximo articulo, para la alta disponibilidad en Asterisk, además de la replicación Master-Master, necesitaremos configurar otros programa. Por ahora nos interesa configurar la replicación MySQL Master-Master.

Escenario:

ServidorA

IP 192.168.142.248

Base de datos a replicar: asterisk – Tabla: cdr

MasterA SlaveA

ServidorB

IP 192.168.146.90

Base de datos a replicar: asterisk – Tabla: cdr

MasterB SlaveB

La tabla CDR en el ServidorA ya existe y tiene unos cuantos datos registrados. El problema principal de la replicación Master-Master es el conflicto que se puede presentar en las entradas de la tabla. Ejemplo:

el servidorA se cae y toma su lugar el servidorB. Se registran unos cuantos datos en la tabla cdr del servidorB. Mientras el servidorA vuelve a funcionar y antes que el servidorB pueda actualizar los datos de la tabla CDR en el servidorA, este empieza a grabar nuevas entradas en la misma tabla. En este escenario se pueden generar conflictos entre los datos de las dos tablas y se genera un error de replicación porque los dos presentan entradas con el mismo ID en la clave primaria de la tabla (siendo progresivo).

Para solucionar este tipo de problema se usarán estos dos parámetros:

  • auto_increment_increment

  • auto_increment_offset


Mano a la obra.

ServidorA


La tabla CDR de la base de datos Asterisk no tiene un ID progresivo para cada entrada. Entramos en el cliente MySQL y miramos la fecha de las llamadas de la extension 2300:

mysql –u root –p

mysql> use asterisk

mysql> select calldate from cdr where dst=2300;

+---------------------+
| calldate            |
+---------------------+
| 2009-10-19 13:16:12 |
| 2009-10-19 13:16:12 |
| 2009-11-04 20:30:48 |
| 2009-11-04 20:30:48 |
| 2009-11-04 20:33:31 |
| 2009-11-04 20:33:31 |
| 2009-11-06 21:03:29 |
| 2009-11-06 21:03:29 |
| 2009-11-06 21:04:09 |
| 2009-11-06 21:04:09 |
| 2009-11-06 21:08:37 |
| 2009-11-06 21:08:37 |
| 2009-12-17 20:59:42 |
| 2009-12-17 20:59:42 |
+---------------------+

14 rows in set (0.01 sec)

Ahora añadimos un id progresivo en la estructura de la tabla:

mysql> ALTER TABLE cdr ADD ID int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY;

Query OK, 2747 rows affected (0.01 sec)
Records: 2747  Duplicates: 0  Warnings: 0


Miramos el cambio:

mysql> select id,calldate from cdr where dst=2300;

+------+---------------------+
| id   | calldate            |
+------+---------------------+
|  610 | 2009-10-19 13:16:12 |
|  611 | 2009-10-19 13:16:12 |
| 1236 | 2009-11-04 20:30:48 |
| 1237 | 2009-11-04 20:30:48 |
| 1238 | 2009-11-04 20:33:31 |
| 1239 | 2009-11-04 20:33:31 |
| 1336 | 2009-11-06 21:03:29 |
| 1337 | 2009-11-06 21:03:29 |
| 1338 | 2009-11-06 21:04:09 |
| 1339 | 2009-11-06 21:04:09 |
| 1342 | 2009-11-06 21:08:37 |
| 1343 | 2009-11-06 21:08:37 |
| 1912 | 2009-12-17 20:59:42 |
| 1913 | 2009-12-17 20:59:42 |
+------+---------------------+
14 rows in set (0.00 sec)


Ahora cada entrada seleccionada tiene un ID que la identifica.

Creamos una carpeta donde guardar los Binary log de MySQL y cambiamos usuario y grupo que tiene los permisos en la carpeta creada:

mkdir /var/log/mysql

chown mysql:mysql /var/log/mysql

ls -l /var/log/my*

-rw-r----- 1 mysql mysql 41201 Feb 24 07:19 /var/log/mysqld.log

/var/log/mysql:
total 0


Volvemos al cliente MySQl y creamos los privilegios de replicación para un nuevo usuario:

mysql –u root –p

mysql> GRANT REPLICATION SLAVE ON *.* TO 'masterb'@'192.168.146.90' IDENTIFIED BY 'sesamo';

mysql> flush privileges;

mysql> quit

Ahora modificamos el archivo de configuración de MySQL:

nano /etc/my.cnf

bajo la etiqueta [mysqld] ponemos:

server-id               = 10
auto_increment_increment = 10
auto_increment_offset    =  1
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
replicate-do-table      =asterisk.cdr
sync_binlog             =1


Los parámetros:

Con auto_increment_increment a 10 cada entrada en la tabla cdr tendrá un ID progresivo que irá de 10 en 10

Con auto_increment_offset a 1 cada entrada usará el entero 1

En el caso de tres entradas en la tabla el resultado será:

ID 1

ID 11

ID 21

Con replicate-do-table definimos que la replicación es solamente para la tabla cdr de la base de datos Asterisk

Reiniciamos mysql:

/etc/init.d/mysql restart

Considerando que nuestro servidor Asterisk tiene tiempo trabajando tenemos que crear una copia de la base de datos para luego importarla en el servidorB:

mysql -u root -p

Primero seleccionamos la base de datos asterisk:

mysql> use asterisk

Segundo bloqueamos la lectura de todas las tablas de todas las bases de datos:

mysql> FLUSH TABLES WITH READ LOCK;

Por ultimo miramos el estado del Master:

mysql> SHOW MASTER STATUS;

Aparecerá algo por el estilo:

+------------------+----------+--------------+------------------+
| File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |       98 | asterisk            |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)


Apuntamos los datos que aparecen en la columna File (mysql-bin.000001) y en la columna Position (98)

Sin cerrar esta ventana, abrimos otra ventana terminal o otra conexión al servidor Linux y creamos una copia de la base de datos asterisk:

cd /tmp

mysqldump -u root -p asterisk cdr > cdr.sql

copiamos el archivo en el servidorB en la carpeta tmp:

scp cdr.sql root@192.168.146.90:/tmp

Cerramos esta ventana y volvemos a la primera:

desbloqueamos las tablas:

mysql> UNLOCK TABLES;

y salimos del cliente:

mysql> quit


ServidorB


Creamos la carpeta para guardar los Bynary log con los permisos para el usuario mysql:

mkdir /var/log/mysql

chown mysql:mysql /var/log/mysql

Entramos en el cliente mysql y creamos la base de datos asterisk:

mysql -u root –p

mysql> create database asterisk;

mysql> quit

Importamos la tabal cdr:

cd /tmp

mysql -u root -p asterisk < cdr.sql

Y averiguamos que efectivamente las tabla y los datos presentes se han guardado:

mysql -u root –p

mysql> use asterisk

mysql> select id,calldate from cdr where dst=2300;

+------+---------------------+
| id   | calldate            |
+------+---------------------+
|  610 | 2009-10-19 13:16:12 |
|  611 | 2009-10-19 13:16:12 |
| 1236 | 2009-11-04 20:30:48 |
| 1237 | 2009-11-04 20:30:48 |
| 1238 | 2009-11-04 20:33:31 |
| 1239 | 2009-11-04 20:33:31 |
| 1336 | 2009-11-06 21:03:29 |
| 1337 | 2009-11-06 21:03:29 |
| 1338 | 2009-11-06 21:04:09 |
| 1339 | 2009-11-06 21:04:09 |
| 1342 | 2009-11-06 21:08:37 |
| 1343 | 2009-11-06 21:08:37 |
| 1912 | 2009-12-17 20:59:42 |
| 1913 | 2009-12-17 20:59:42 |
+------+---------------------+
14 rows in set (0.01 sec)

Creamos un nuevo usuarios con los permisos de replicación

mysql> GRANT REPLICATION SLAVE ON *.* TO 'mastera'@'192.168.142.248' IDENTIFIED BY 'sesamo';

mysql> flush privileges;

mysql> quit

Ahora modificamos el archivo de configuración de MySQL:

nano /etc/my.cnf

bajo la etiqueta [mysqld] ponemos:

server-id               = 20
auto_increment_increment = 10
auto_increment_offset    =  2
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
replicate-do-table      =asterisk.cdr
sync_binlog             =1


El auto_increment_offset es igual a 2. En el caso de tres entradas el ID sería:

ID 2

ID 12

ID 22

Como pueden ver, de esta forma no se presentarán conflictos en las entradas de la tabla CDR

Reiniciamos Mysql:

/etc/init.d/mysqld restart

Y ahora como para el servidorA miramos el Binary log y apuntamos los datos:

mysql -u root -p

mysql> FLUSH TABLES WITH READ LOCK;

mysql> SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |       98 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)


mysql> quit

Ahora conectamos el servidorB al servidorA:

mysql -u root –p

mysql> CHANGE MASTER TO MASTER_HOST='192.168.142.248',
MASTER_USER='masterb',
MASTER_PASSWORD='sesamo',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=98;
Query OK, 0 rows affected (0.00 sec)


Iniciamos el esclavo:

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)

y miramos el resultado:

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.142.248
Master_User: masterb
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table: asterisk.cdr
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)

Seguimos el mismo procedimiento para el ServidorA:

mysql –u root –p

mysql> CHANGE MASTER TO MASTER_HOST='192.168.146.90',
MASTER_USER='mastera',
MASTER_PASSWORD='sesamo',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=98;
Query OK, 0 rows affected (0.10 sec)


mysql> START SLAVE;

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.146.90
Master_User: mastera
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table: asterisk.cdr
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)

Ahora la prueba.

Paramos el MySQL del servidorB y hacemos dos llamadas al buzón de voz con asterisk activo en el servidorA

El resultado en la base de datos:

mysql -u root -p

mysql> use asterisk

mysql> select id,calldate from cdr where dst=97;

| 2736 | 2010-02-23 13:06:56 |
| 2737 | 2010-02-23 13:06:56 |
| 2738 | 2010-02-24 06:05:53 |
| 2739 | 2010-02-24 06:05:53 |
| 2791 | 2010-02-24 09:48:44 |
| 2801 | 2010-02-24 09:49:00 |
+------+---------------------+
207 rows in set (0.00 sec)

Mientras antes el ID era progresivo, las ultimas dos entradas tienen un salto de 10 y cada una termina con el numero 1

Terminada la operación, paramos MySQL en el servidorA y iniciamos MySQL en el servidorB haciendo dos llamadas al buzón de voz usando el Asterisk del servidorB

El resultado en la base de datos:

mysql -u root -p

mysql> use asterisk

mysql> select id,calldate from cdr where dst=97;

| 2736 | 2010-02-23 13:06:56 |
| 2737 | 2010-02-23 13:06:56 |
| 2738 | 2010-02-24 06:05:53 |
| 2739 | 2010-02-24 06:05:53 |
| 2752 | 2010-02-24 09:55:07 |
| 2762 | 2010-02-24 09:57:17 |
+------+---------------------+
207 rows in set (0.01 sec)

El ID progresivo en el servidorB cambia con saltos de 10 y cada entrada termina con el numero 2

Ahora iniciamos MySQL en el servidorA y miramos que pasa en los dos servidores:

ServidorA:

mysql -u root –p

mysql> use asterisk

mysql> select id,calldate from cdr where dst=97;

| 2737 | 2010-02-23 13:06:56 |
| 2738 | 2010-02-24 06:05:53 |
| 2739 | 2010-02-24 06:05:53 |
| 2752 | 2010-02-24 09:55:07 |
| 2762 | 2010-02-24 09:57:17 |
| 2791 | 2010-02-24 09:48:44 |
| 2801 | 2010-02-24 09:49:00 |
+------+---------------------+
209 rows in set (0.00 sec)


ServidorB

mysql -u root –p

mysql> use asterisk

mysql> select id,calldate from cdr where dst=97;

| 2739 | 2010-02-24 06:05:53 |
| 2752 | 2010-02-24 09:55:07 |
| 2762 | 2010-02-24 09:57:17 |
| 2791 | 2010-02-24 09:48:44 |
| 2801 | 2010-02-24 09:49:00 |
+------+---------------------+
209 rows in set (0.01 sec)


Los datos se han replicado y no hubo ningún tipo de conflicto en la tabla cdr gracias al uso de:

auto_increment_increment
auto_increment_offset


Aqui pongo la fuente ya que una señorita corrió diciendo que me robe el post jaja casualmente yo envie un trackback, pero bueno dedicado a la señorita o señora Andrea Sannucci

FUENTE

SafiServer and SafiWorkshop (version 1.3RC1) estan disponibles

SafiServer and SafiWorkshop (version 1.3RC1) esta disponibles para la descarga. Se ha arreglado varios bugs encontrados en la version 1.3 Beta

He aquí algunas de los fixes realizados a esta versión:

  • BUG FIX: Issue with SaveAs function

  • BUG FIX: Boolean Editor missing in SafiWorkshop

  • ExecuteApplication: Application property changed to dynamic value

  • Fixed underlying bug with ThreadLocal vars in SafiServer that was causing errors

  • The Linux installer and service scripts are back (tested on CentOS)


thumb_newlinuxinstallerPara instalar el  Linux SafiServer, descomprimimos el archivo descargado en el directorio que querramos:

tar zxfv SafiServer-1.3.0.RC1.tar.gz
Corremos el script de instalación (localizado en el directorio root de  SafiServer)

cd SafiServer-1.3.0./installserver.sh

Deberiamos ver la siguiente información:

Fill in the appropriate information and the service should start automatically. Note: SafiServer startup may take a few minutes. You can verify that the service is running by looking in the karaf.log file (found at my_install_dir/SafiServer-1.3.0/date/log/karaf.out). You should see the following line after the server has started:

Listening on *:4573.

Download now!

lunes, 26 de abril de 2010

Asterisk y la replicación MySQL Master-Slave en CentOS

En esta ocasión les traigo unos buenos post que hallé en voztovoice, se trata de la replicación de las BD's de los CDR en Asterisk, un agradecimiento por su gran esfuerzo.

Tenemos nuestro servidor Asterisk instalado y trabajando con los registros de las llamadas guardados en una base de datos MySQL. Queremos tener una copia de la base de datos actualizada en tiempo real para hacer frente a cualquier tipo de evento que pueda afectar la integridad de los registros de las llamadas. En este tipo de escenario tenemos a disposición una funcionalidad de MySQL; la posibilidad de replicar los datos en un servidor MySQL instalado en otro computador. Tenemos dos formas de replicar los datos:

  • configurar una replicación master-slave (maestro-esclavo)

  • configurar una replicación master-master (maestro-maestro)


En este primer articulo sobre el tema, veremos como crear una replicación MySQL master-slave. La replicación master-slave no es una copia de backup de la base de datos, de hecho si borramos una entrada en el MySQL maestro, automáticamente se borrará también en el esclavo. La idea es tener siempre una copia de backup y además crear la replicación maestro-esclavo.

Podemos usar el esclavo para consultas desde otros programas y de esta manera no cargar demasiado el Maestro. Un ejemplo puede ser cuando vamos a generar reportes mensuales de las llamadas. En vez de hacer las consultas en el maestro, las podemos hacer en el esclavo.

Es buena practica usar una conexión dedicada para el intercambio de datos entre el maestro y el esclavo para evitar que hayan retrasos considerables en la actualización de la base de datos.

¿Como funciona la replicación MySQL Master-slave?

  • El Maestro registra los cambios en un registro binario (Binary log)

  • El esclavo copia los eventos en un registro propio (Relay log)

  • El esclavo lee y repite los eventos presentes en el Relay log en la base de datos


Una imagen que explica el funcionamiento:


El escenario que se va a presentar en este articulo es el siguiente:

ServidorA:

IP LAN: 192.168.142.248

Base de datos a replicar: asterisk

Master

ServidorB:

IP LAN: 192.168.146.90

Esclavo

Servidor A:


Creamos una carpeta donde guardar los Binary log:

mkdir /var/log/mysql

Cambiamos los permisos de modo que MySQL pueda escribir y leer en esa carpeta:

chown mysql:mysql /var/log/mysql

Entramos en el cliente mysql

mysql -u root -p

y creamos los privilegios de replicación para un nuevo usuario que luego configuraremos en el servidorB:

myslq> GRANT REPLICATION SLAVE ON *.* TO 'fulano'@'192.168.146.90' IDENTIFIED BY 'sesamo';

Actualizamos los privilegios y salimos del cliente MySQL:

mysql> flush privileges;

mysql> quit

Ahora modificamos el archivo de configuración de MySQL para configurar los parámetros necesarios para la replicación:

nano /etc/my.cnf

Bajo la etiqueta [mysqld] añadimos las siguientes línea:

server-id               = 10
log_bin                 = /var/log/mysql/mysql-bin.log
expire_logs_days        = 10
max_binlog_size         = 100M
binlog_do_db            = asterisk
sync_binlog=1


Una pequeña explicación de los parámetros:

  • server-id: identifica el servidor MySQL.

  • log_bin: nombre del archivo donde se guardará el Binary log

  • expire_log_days: especifica que los archivos Binary log más viejos de 10 días se pueden borrar

  • max_binlog_size: el tamaño máximo de un Binary log

  • binlod_do_db: el nombre de la base de datos que queremos replicar

  • sync_binlog=1: cada evento generado en el Master será escrito inmediatamente en el Binary log. Aumenta la carga del Master a cambio de una replicación más precisa


Guardamos los cambios y reiniciamos MySQL

/etc/init.d/mysql restart

Considerando que nuestro servidor Asterisk tiene tiempo trabajando tenemos que crear una copia de la base de datos para luego importarla en el servidor MySQL esclavo:

mysql -u root -p

Primero seleccionamos la base de datos asterisk:

mysql> use asterisk

Segundo bloqueamos la lectura de todas las tablas de todas las bases de datos:

mysql> FLUSH TABLES WITH READ LOCK;

Por ultimo miramos el estado del Master:

mysql> SHOW MASTER STATUS;

Aparecerá algo por el estilo:

+------------------+----------+--------------+------------------+
| File                    | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |       98 | asterisk            |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)


Apuntamos los datos que aparecen en la columna File (mysql-bin.000001) y en la columna Position (98)

Sin cerrar esta ventana, abrimos otra ventana terminal o otra conexión al servidor Linux y creamos una copia de la base de datos asterisk:

cd /tmp

mysqldump -u root -psesamo asterisk > asteriskslave.sql

copiamos el archivo en el servidoB en la carpeta tmp:

scp asteriskslave.sql root@192.168.146.90:/tmp

Cerramos esta ventana y volvemos a la primera:

desbloqueamos las tablas:

mysql> UNLOCK TABLES;

y salimos del cliente:

mysql> quit

Servidor B


Si no tenemos instalado MySQL, lo instalamos:

yum install mysql mysql-server mysql-devel

Lo iniciamos:

/etc/init.d/mysqld start

Creamos una contraseña para el usuario root:

mysqladmin –u root password sesamo

Modificamos el archivo de configuración de MySQL

nano /etc/my.cnf

bajo la etiqueta [mysqld] ponemos:

server-id=20
master-connect-retry=60
replicate-do-db=asterisk
skip_slave_start
read_only


Los parámetros:

  • server-id: numero que identifica el servidor MySQL del servidorB

  • master-connect-retry=60: si el esclavo pierde la conexión con el maestro, cada 60 segundos intentará restablecerla

  • replicate-do-db: la base de datos que vamos a replicar

  • skip_slave_start: evita que el esclavo se reinicie en el caso de un crash del servidor

  • read_only: no permite a la mayoría de los usuarios del servidor MySQL esclavo cambiar las tablas


Guardamos los cambios y volvemos a arrancar MySQL:

/etc/init.d/mysqld restart

Creamos la base de datos asterisk:

mysqladmin -uroot -psesamo create asterisk

recuperamos tablas y datos de la copia que tenemos en la carpeta /tmp:

cd /tmp

mysql -u root -psesamo asterisk < asteriskslave.sql

Llegados a este punto creamos los datos de acceso al servidor MySQL Master:

mysql -u root -psesamo

mysql> CHANGE MASTER TO MASTER_HOST='192.168.142.248',
MASTER_USER='fulano',
MASTER_PASSWORD='sesamo',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=98;


En MASTER_LOG_FILE Y MASTER_LOG_POS, ponemos los datos del servidor MySQL A que habíamos apuntado.

Iniciamos el esclavo:

mysql> START SLAVE;

Controlamos el estado de la conexión con el Master:

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.142.248
Master_User: fulano
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: asterisk
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)

Salimos del cliente:

mysql> quit

Ahora hacemos una llamada de prueba y miramos que pasa en el servidorA (captura de paquetes en el puerto 3306 con ngrep):

#
T +7.266866 192.168.142.248:3306 -> 192.168.146.90:58745 [AP]
:......~K.
...9.........
..............@.............std.......asterisk.INSERT INTO cdr (calldate,src,dst,dcontext,channel,lastapp,duration,billsec,disposition,amaflags,accountcode,uniqueid) VALUES ('2010-02-19 12:34:14','2100','97','phones','SIP/2100-00000001','Hangup','26','26','ANSWERED','3','2100','1266600854.1')
##

El servidorA 192.168.142.248:3306 envía un paquete al servidorB 192.168.146.90:58745 que contiene los datos de la llamada. El ServidorB guarda los datos en su Relay log y luego de leer el Relay log los guarda en la base de datos.

Esto es todo, un largo pero enriquecedor artículo

Asterisk 1.8 mejorará considerablemente el soporte de FAX

Aunque la esperada versión de Asterisk 1.8 no verá la luz hasta dentro de muy pocos meses, nos empiezan a llegar algunas novedades sobre las mejoras que se están preparando entre ellas la incorporación de una mejora considerable en el soporte de Fax (principalmente el soporte de T.38) que en Asterisk 1.4 era bastante rudimentario (únicamente permitía pasar paquetes T.38 mediante SIP e incluso tenía ciertas incompatibilidades en función del tipo de gateway que se utilizara), y en Asterisk 1.6 se mejoró un poco aunque seguía sin ser todo lo que realmente se esperaba de él (la implantación de Steve Underwood con la creación del spandsp y de algunos módulos extras permitieron mejorar este soporte, aunque no era todo lo que en un principio se esperó que fuera) y se espera que en Asterisk 1.8 se pueda contar con un soporte completo de faxes(tanto de T.30 -la forma habitual a través de audio- como de T.38 -digitalizando el fax y permitiendo una confirmación de recepción lo que aseguraría el envío y la recepción de faxes entre dispositivos que utilizan este protocolo-).

Kevin P. Flemming anunciaba el otro día que varios desarrolladores de Digium se habían puesto manos a la obra para plantear y empezar a desarrollar un soporte en condiciones para los faxes (pese a que utilizar faxes, es y seguirá siendo, una tecnología totalmente obsoleta y que debería desaparecer).

Gracias a la experiencia obtenida por el desarrollo del módulo comercial Fax for Asterisk de Digium que mejora considerablemente la velocidad y la calidad de envío y recepción de faxes (que por cierto, parece ser que ya es compatible con sistemas de 64bits), Asterisk 1.8 contará con una implementación similar utilizando un stack propio de forma que este soporte sí se pueda licenciar como un producto GPL y pueda integrarse en la próxima versión de Asterisk.

De forma que, aunque en Asterisk 1.6 el soporte de Faxes es ya bastante bueno, Asterisk 1.8 contará con un soporte mucho mejor y que hará las delicias de aquellos usuarios que utilicen faxes.

Voice Operator Panel

Voice Operator Panel (VOP) es un SIP Softphone professional para operadoras y recepcionistas con integración con Outlook /LDAP/MSN/CRM, incorporado en el navegador web y e-mailing. VOP puede ser usado como un Softphone independiente o combinado con cualquier teléfono análogo o de Voip para recibir llamadas.
VOP ofrece un espacio de trabajo completamente personalizable con la misma piel de la suite Microsoft Office.

VOP proporciona un control completo estado de extensión (de llamada, ocupado, disponible) con los detalles y la intercepción de llamadas de llamadas.

VOP es ideal para operadores IP Centrex IP y PBX instaladores que quieran ofrecer a sus clientes un cuadro de distribución de software avanzado y consola de operadora.

VOP es de 100% compatibles con SIP, ha sido plenamente validado con Cirpack, Communigate, Enswitch, pbxnsip, 3CX, Asterisk, sipXecs, OpenSIPS y trabajará con cualquier softswitch, PBX IP o un proxy SIP.
VOP también está disponible en una edición Lite para recepcionistas las pequeñas empresas y para llamar a los agentes centros, y en un compacto Edición Micro para ordenadores de escritorio.

Download now!