Friday, May 19, 2006

What are my address handles?

I am following on Simon's last post, where he mentioned how discovery of contact details was an essential piece in integrating multiple addressing namespaces through XMPP. This discussion originated from his work on integrating his XMPP server with an Asterisk PBX. Beyond the specific mapping needs we identified for his application, I believe XMPP must provide a standard way of querying a service entity to discover what address handles are related to a JID. The original question was "I need to know the PBX extension for each of my XMPP users. How can my client query a service to retrieve this information?". This kind of legitimate question is typical of any interface between XMPP and another protocol. The client could either be a typical GUI client, or simply a gateway service trying to access address mapping information from an identity repository.

From a functional design perspective, these requirements lead to using some sort of address handle registrar. This registrar could then be queried to return non XMPP address handles for any JID. The purpose of this post is not in defining the implementation of this registrar service, but rather explaining how we can leverage existing XMPP extensions to obtain the expected result. And when it comes to available services and features, the obvious answer in XMPP is to turn to service discovery. Discovery is always a two steps process at a minimum:

  • discover the service identity and its JID
  • query the service for detailed information

The service identity discovery is achieved by by issuing a generic item discovery to one’s XMPP home server.

<iq type='get' from='romeo@montague.net/orchard'>
      to='shakespeare.lit'
      id='items1'>
     <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

The server will provide a response similar to:

<iq type='result'
      from='shakespeare.lit'
     to='romeo@montague.net/orchard'
      id='items1'>
      <query xmlns='http://jabber.org/protocol/disco#items'>
          <item jid='registrar.shakespeare.lit'
                    name='Directory of Characters'/>
          <item jid='jingle.shakespeare.lit'
                   name='Play Media Gateway’/>
          …
      </query>
</iq>

In the second step, the client will go over the list of identities that was returned by the server, querying each of them in turn to obtain their supported features. To that effect, the client will issue targeted discovery information queries to each returned service JID. At some point the registrar service will receive:

<iq type='get' from='romeo@montague.net/orchard'
      to='registrar.shakespeare.lit'
      id='info1'>
      <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

And will return its information set in a response such as this one:

<iq type='result'
      from='registrar.shakespeare.lit'
      to='romeo@montague.net/orchard'
      id='info1'>
      <query xmlns='http://jabber.org/protocol/disco#info'>
           <identity category='directory'
                         type='user'
                         name='Directory of Characters'/>
           <identity category='directory'
                         type='address'
                         name='Characters White Pages'/>
           …
          <feature var='jabber:iq:search'/>
          <feature var='http://jabber.org/address#mapping'/>
          …
      </query>
</iq>

This (non normative) example illustrate how a client application would leverage service discovery to find about an address handle mapping service on the XMPP network. You will note how the discovery uses the new identity type "address" in the existing "directory" category to indicate that if can provide address handle mapping information. The features set provide additional information by specifying that queries will be understood in the "http://jabber.org/address#mapping" namespace. Once again we leverage existing XMPP specifications. The "http://jabber.org/address" is already defined and one possible usage is described in JEP-0033. I explained in an earlier post how we can leverage this existing specification and extend it in the context of Jingle. I am presenting yet another extension to query address mappings. The extended addressing schema supports non XMPP address namespaces by the use of an URI attribute instead of a JID. This is what we are going to use here.

To progress further, the client application will have to discover what actual mapping the service provides. It is matter for item discovery. The client will issue a query to the service in the form of:

<iq type='get'
      from='romeo@montague.net/orchard'
      to='registrar.shakespeare.lit'
      id='items2'>
      <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>

To this query, the service will answer with a list of nodes indicating the various addressing namespaces for which it can provide a translation.

<iq type='result'
      from='registrar.shakespeare.lit'
      to='romeo@montague.net/orchard'
      id='items2'>
      <query xmlns='http://jabber.org/protocol/disco#items'>
           <item jid='registrar.shakespeare.lit'
                    node='http://jabber.org/address/mailto'
                    name='Characters eMails'/>
           <item jid='registrar.shakespeare.lit'
                    node='http://jabber.org/address/sip'
                    name='Characters SIP address of record'/>
           <item jid='registrar.shakespeare.lit'
                    node='http://jabber.org/address/iax2'
                    name='Characters phone extensions'/>
           <item jid='registrar.shakespeare.lit'
                    node='http://jabber.org/address/tel'
                    name='Characters phone numbers'/>
          ...
      </query>
</iq>

The service indicates in its response is willing to provide address mappings in the mailto, sip, iax2 and tel URI namespaces. At this point the client application only needs to issue a query to one of the namespaces' node to discover the address mapping.

<iq type='get'
      from='romeo@montague.net/orchard'
      to='registrar.shakespeare.lit'
      id='items3'>
      <query xmlns='http://jabber.org/protocol/disco#items'
                  node='http://jabber.org/address/tel'/>
</iq>

<iq type='result'
      from='registrar.shakespeare.lit'
      to='romeo@montague.net/orchard'
      id='items3'>
      <query xmlns='http://jabber.org/protocol/disco#items'
                 node='http://jabber.org/address/tel'>
            <item jid='romeo@montague.net'>
                <addresses xmlns='http://jabber.org/protocol/address'>
                    <address type='to' uri='tel:+16135555555'/>
                </addresses>
            </item>
            ...
      </query>
</iq>

At this point, the client application has been able to retrieve the mapping between its own JID and and its address handle for the phone namespace. In the case of Simon's application, it will have to retrieve the mapping for the IAX namespace, and would then be able to populate its Jingle transport candidates with the appropriate information.

Technorati Tags: , , , , , , ,

Labels: