OpenSIPS 2.2: Creating WebAPI
OpenSIPS has multiple modules to interact with it in realtime. Sometimes we need to pull information out of the proxy and sometimes we need to insert, or check status of other modules.
Here is a list of module which can be used to achieve the objective:
MI_DATAGRAM | DATAGRAM (unix and network) support for Management Interface | stable |
MI_FIFO | FIFO support for Management Interface | stable |
MI_HTTP | HTTP support for Management Interface | stable |
MI_JSON | JSON support via HTTP GET for Management Interface | beta |
MI_XMLRPC_NG | XMLRPC support for Management Interface | beta |
In my last blog on this topic I showed how to use module MI_XMLRPC to monitor the status of OpenSIPS: Read it here. That mi_xmlrpc module is now obsolete and a newer module mi_xmlrpc_ng has taken its place.
Today we will use the new module with OpenSIPS and see how we can query our server from the internet to do something.
First we need to know what we require to get started.
1 - HTTPD module, and MI_XMLRPC_NG module installed with OpenSIPS 2.2
2 - Apache2/ httpd running on the Server.
OpenSIPS' HTTPD module is a requirement since this module provides the web related backend to its other modules.
Lets load up this module into our opensips.cfg
loadmodule "httpd.so" modparam("httpd", "ip", "127.0.0.1") modparam("httpd", "port", 8887) modparam("httpd", "buf_size", 524288) modparam("httpd", "post_buf_size", 4096)
Next we need to load mi_xmlrpc_ng module.loadmodule "mi_xmlrpc_ng.so" modparam("mi_xmlrpc_ng", "http_root", "mybox")
The root directory 'mybox' can be anything and it does not represent any folder in the operating system. That infact tells us that when we start up our OpenSIPS the port for http will be 8887, and the web root directory allocated for mi_xmlrpc_ng module would be 'mybox' .
Web API script
Next we need to create the script that will be responsible to collect Requests from internet and then pass them to OpenSIPS, return data if any.
This script can be written in any language, Pythin, PHP, Perl, GoLang, Ruby, whatever your language of choice for creating a web-api is use is. I'd kept it simple and use PHP.
Complete script link: https://github.com/goharahmed/scripts/blob/master/webapi.php
Copy the script into your Apache2 webroot directory , say file 'webapi.php'
Copy the script into your Apache2 webroot directory , say file 'webapi.php'
<?php $opensip_ip = '127.0.0.1'; //Should use the same HTTPD PORT as declared in opensips.cfg $opensip_xmlrpc_port = '8887'; //Should use the same webroot as declared in mi_xmlrpc_ng module parameters $xmlrpc_root = 'mybox'; $count = 0; $method; $param; $web_req = 0; if(isset($_GET) && isset($_GET['method'])){ foreach($_GET as $key => $value) { if($key == 'method') { $method = $value; } if(preg_match("/^param\d$/",$key)) { $param[] = $value; } } $web_req = 1; } else { foreach ($argv as $arg) { if($count==1) $method = $arg; else if($count>1) { $param[] = $arg; } $count++; } } $request = xmlrpc_encode_request($method,$param); $context = stream_context_create(array('http' => array( 'method' => "POST", 'header' => "Content-Type: text/xml", 'content' => $request ))); // Dispatchs Request to Local OpenSIPS instance $server = 'http://'.$opensip_ip.':'.$opensip_xmlrpc_port.'/'.$xmlrpc_root; //Collect Result from opensips module $file = file_get_contents($server, false, $context); //Decode the XML into Array $response = xmlrpc_decode($file); if (is_array($response)) { /* We can filter and sort Output here to do whatever you want to do */ /* if($method == 'ul_show_contact') { Then filter only the required fields to be sent back } else if ($method == 'ds_list') { Then filter the output to show only the active servers } */ if($web_req == 0) { RecursiveWrite($response); }else if($web_req == 1) { print_r(json_encode($response)); } } function RecursiveWrite($array) { foreach ($array as $key => $vals) { if(is_array($vals)){ RecursiveWrite($vals); } else { print "$key $vals\n"; } } } ?>
Now, make sure your opensips is restarted to include the new module, make sure your server is able to listen to the web requests. Time to send requests to our OpenSIPS.
Open your browser and paste the following URL to find if a particular suer is Online or Not.
http://YourServerIPHere/webapi.php?method=ul_show_contact¶m1=location¶m2=gohar@saevolgo.ca
param1 = The database table where the User Registrations are stored.
param2 = The AoR to find if Online
You can add as many param as you want , param3, param4...paramN depending if the MI command needs or not.
If a command requires no parameter then don't add any for example:
http://YourServerIPHere/webapi.php?method=lb_list
http://YourServerIPHere/webapi.php?method=ul_show_contact¶m1=location¶m2=gohar@saevolgo.ca
Little Explanation:
method = MI command to query the user location statusparam1 = The database table where the User Registrations are stored.
param2 = The AoR to find if Online
You can add as many param as you want , param3, param4...paramN depending if the MI command needs or not.
If a command requires no parameter then don't add any for example:
http://YourServerIPHere/webapi.php?method=lb_list
To get Statistics:
http://YourServerIPHere/webapi.php?method=get_statistics¶m1=tm:
OpenSIPS Modules: How to read what command has how many parameters ?
Take example of Load-Balancer module:
The function lb_relaod has no parameters:
:lb_reload:_reply_fifo_file_ _empty_line_
So my URL would be:
http://YourServerIPHere/webapi.php?method=lb_reload
But the function lb_resize takes 3 parameteres:
:lb_resize:_reply_fifo_file_ 11 /*dstination id*/ voicemail /*resource name*/ 56 /* new resource capacity*/ _empty_line_
For above the URL would be:
http://YourServerIPHere/webapi.php?method=lb_resize¶m1=11¶m2=voicemail¶m3=56
Thats pretty much all, thanks for reading.