msgbartop
The rants and raves of a technogeek
msgbarbottom

msgbartop
msgbarbottom

08 Oct 08 app_xmlrpc_request

New application: app_xmlrpc_request

While at the DevCon, i’ve talked to some of the people, explaining a simple methodology of how I make my AGI applications highly scaleable and easy to manage, utilizing an XML-RPC request methodology. Allowing my dialplan to initiate XML-RPC requests to an external web service, obtain information, and then instruct Asterisk to execute dialplans accordingly. This had brought up the idea of writing an XML-RPC requester application for Asterisk, allowing a developer to utilizing a core application, in stead of using external AGI.

Following below is a description of how the application will be built, how it works, configured and how to interact with it:

Objective

app_xmlrpc_request will allow an Asterisk dialplan to perform a direct XML-RPC request to a remote XML-RPC server, utilizing a well formatted request, as defined by a predefined configuration file.

What is XML-RPC?

According to the xmlrpc.org website, XML-RPC is defined as:

It's a spec and a set of implementations that allow software running on disparate operating systems,
running in different environments to make procedure calls over the Internet.

It's remote procedure calling using HTTP as the transport and XML as the encoding. XML-RPC is designed
to be as simple as possible, while allowing complex data structures to be transmitted, processed and
returned.

Taking the above into consideration, we are now required to understand how XML-RPC works.

An XML-RPC request

The code below illustrates and XML-RPC request:

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181

<?xml version="1.0"?>
  <methodCall>
    <methodName>examples.getStateName</methodName>
    <params>
      <param>
        <value><i4>41</i4></value>
        </param>
      </params>
    </methodCall>

The above illustrates an XML-RPC that contains a method name and a single variable. While the above is fairly simplistic, XML-RPC is fully capable of traversing a multiple number of variables, via structures. An example follows:

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181

<?xml version="1.0"?>
  <methodCall>
    <methodName>examples.calculateCenter</methodName>
    <struct>
      <member>
        <name>lowerBound</name>
        <value><i4>18</i4></value>
        </member>
      <member>
        <name>upperBound</name>
        <value><i4>139</i4></value>
        </member>
      </struct>
    </methodCall>

Other values can also be passed as part of the structure, such as strings, booleans, dates and arrays. A complete listing and specification is available at http://www.xmlrpc.org.
Once a request had been sent to the processing XML-RPC server, a response is sent back, utilizing a similar structure. The response is formatted according to the following:

HTTP/1.1 200 OK
Connection: close
Content-Length: 158
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:08 GMT
Server: UserLand Frontier/5.1.2-WinNT

<?xml version="1.0"?>
  <methodResponse>
    <params>
      <param>
        <value><string>South Dakota</string></value>
        </param>
      </params>
    </methodResponse>

Or in a case where the response indicates a failure:

HTTP/1.1 200 OK
Connection: close
Content-Length: 426
Content-Type: text/xml
Date: Fri, 17 Jul 1998 19:55:02 GMT
Server: UserLand Frontier/5.1.2-WinNT

<?xml version="1.0"?>
  <methodResponse>
    <fault>
      <value>
        <struct>
          <member>
            <name>faultCode</name>
            <value><int>4</int></value>
            </member>
          <member>
            <name>faultString</name>
            <value><string>Too many parameters.</string></value>
            </member>
          </struct>
        </value>
      </fault>
    </methodResponse>

Utilizing the above structures, our aim is to allow Asterisk to communicate with an external XML-RPC server, allowing information traversal from external sources that are based upon XML-RPC web services.

xmlrpc_client.conf

The xmlrpc_client.conf file contains configuration contexts for performing XML-RPC requests. A configuration context will contain the request URL, the method name (as defined by XML-RPC) and the XML-RPC request format structure.
Our XML-RPC requester context will contain a set of identifiers, allowing the developer to create an expendable environment for creating XML-RPC templates. The following is an example of how our configuration file will look:

[xrpc_calculateCenter]
request_method  = example.calculateCenter
request_server  = http://some.fqdn.or.ip/xmlserver.script
request_format  = S{lowerBound:i,upperBound:i}

In order to activate the xmlrpx_request application, the invocation will follow the following format:

exten => _X.,n,Set(HASH(inHash,lowerBound)=18)
exten => _X.,n,Set(HASH(inHash,upperBound)=139)
exten => _X.,n,xmlrpc_request(xrpc_calculateCenter,inHash,outHash)
exten => _X.,n,Noop(at this point, outHash will contain the returned values from the XML-RPC request)

The application will know that the request utilizes a specific format, while extracting the variables from the channel in order to incorporate these into the request itself.

xmlrpc_client.conf – configuration file example

[general]
fourtytwo = 42

[xrpc_calculateCenter]
request_method  = example.calculateCenter
request_server  = http://betty.userland.com/xmlserver.script
request_format  = S{lowerBound:i,upperBound:i}

[xrpc_getStateName]
request_method  = examples.getStateName
request_server  = http://betty.userland.com/xmlserver.script
request_format  = i

The request format indicates how our parameters are formatted, according to the following rules:
1. A single value may be passed. Any type from the below table may be used.
2. A single array may be passed using the A{} operator.
3. Multiple valued may be passed using structures, utilizing the S{} operator.

The below table contains the various format identifiers:

specifier XML-RPC type
i 32 bit integer (<int>)
b boolean (<boolean>)
d double precision floating point number (<double>)
c string (<string>)
z base64-encoded byte string (<base64>)
t date/time (<dateTime.iso8601>)
a array (<array>)
s structure (<struct>)

Lowercase characters mean that the field is optional; upper case characters declare the field as mandatory across all requests.

Implementation Path

Library Dependency

The library of choice for this implementation is located at http://xmlrpc-c.sourceforge.net/, and is licensed under the BSD license terms, making it ideal for integration with the Asterisk core code.



Leave a Comment

You must be logged in to post a comment.