Files
spring-integration/docs/src/reference/docbook/xmpp.xml
2010-11-13 12:30:48 -05:00

245 lines
13 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="xmpp"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>XMPP Support</title>
<para>
Spring Integration provides Channel Adapters for <ulink url="http://www.xmpp.org">XMPP</ulink>.
</para>
<section id="xmpp-intro">
<title>Introduction</title>
<para>
XMPP describes a way for multiple agents to communicate with each other in a distributed system.
The canonical use case is to send and receive chat messages, though XMPP can be, and is, used for far more
applications.
XMPP is used to describe a network of actors. Within that network, actors may address each other directly, as well
as broadcast status changes (e.g. "presence").
</para>
<para>
XMPP provides the messaging fabric that underlies some of the biggest Instant Messaging networks in the world,
including Google Talk (GTalk) - which is also available from within GMail - and Facebook Chat.
There are many good open-source XMPP servers available. Two popular implementations are
<ulink url="http://www.igniterealtime.org/projects/openfire/">
<citetitle>Openfire</citetitle>
</ulink>
and
<ulink url="http://www.ejabberd.im">
<citetitle>ejabberd</citetitle>
</ulink>
</para>
<para>
Spring integration provides support for XMPP via XMPP adapters which support sending and receiving both XMPP chat messages and
presence changes from other entries in your roster. As many other adapters, XMPP adapters come with a convenient namespace-based
configuration.
To configure XMPP namespace include the following elements into the headers of your XML configuration file:
<programlisting language="xml"><![CDATA[xmlns:xmpp="http://www.springframework.org/schema/integration/xmpp"
xsi:schemaLocation="http://www.springframework.org/schema/integration/xmpp
http://www.springframework.org/schema/integration/xmpp/spring-integration-xmpp-2.0.xsd"]]></programlisting>
</para>
</section>
<section id="xmpp-connection">
<title>XMPP Connection</title>
<para>
Before using inbound or outbound XMPP adapters to participate in the XMPP network actor must establish XMPP connection. This
connection object could be shared by all XMPP adapters connected to a particular account. Typically this requires - at a minimum -
<code>user</code>, <code>password</code>, <code>host</code>.
To create a basic XMPP connection, you can utilize the convenience of the namespace.
<programlisting lang="xml"><![CDATA[<xmpp:xmpp-connection
id="myConnection"
user="user"
password="password"
host="host"
port="port"
resource="theNameOfTheResource"
subscription-mode="accept_all"/>
]]></programlisting>
</para>
</section>
<section id="xmpp-messages">
<title>XMPP Messages</title>
<section id="xmpp-message-inbound-channel-adapter">
<title>Inbound Message Channel Adapter</title>
<para>The Spring Integration adapters support receiving chat messages from other users in the system. To do this, the
<emphasis>Inbound Message Channel Adapter</emphasis> "logs in" as a user on your behalf and receives the messages sent to that user. Those messages are then
forwarded to your Spring Integration client.
The payload of the inbound Spring Integration message may be of the raw type<classname>
org.jivesoftware.smack.packet.Message</classname>, or of the type
<classname>java.lang.String</classname> if you set <code>extract-payload</code> value attribute to 'true'
when configuring an adapter.
Configuration support for the XMPP <emphasis>Inbound Message Channel Adapter</emphasis> is provided via the <code>inbound-channel-adapter</code> element.
<programlisting language="xml"><![CDATA[<xmpp:inbound-channel-adapter id="xmppInboundAdapter"
channel="xmppInbound"
xmpp-connection="testConnection"
extract-payload="false"
auto-startup="true"/>]]></programlisting>
As you can see amongst the usual attributes this adapter also requires a reference to an XMPP Connection.
</para>
<para>
It is also important to mention that XMPP inbound adapter is an <emphasis>event driven adapter</emphasis> and a <classname>LifeCycle</classname> object.
When started it will register a <classname>PacketListener</classname> that will listen for the incoming XMPP Messages. It forwards those messages
to the underlying adapter which will convert them to Spring Integration Messages and send them to the <classname>channel</classname>. It will
unregister the <classname>PacketListener</classname> when it is stopped.
</para>
</section>
<section id="xmpp-message-outbound-channel-adapter">
<title>Outbound Message Channel Adapter</title>
<para>
You may also send chat messages to other users on XMPP using the <emphasis>Outbound Message Channel Adapter</emphasis>.
Configuration support for the XMPP <emphasis>Outbound Message Channel Adapter</emphasis> is provided via the <code>outbound-channel-adapter</code> element.
<programlisting language="xml"><![CDATA[<int-xmpp:outbound-channel-adapter id="outboundEventAdapter"
channel="outboundEventChannel"
xmpp-connection="testConnection"/>]]></programlisting>
The adapter expects as its input - at a minimum - a payload of type <classname>java.lang.String</classname>, and a header value
for <classname>XmppHeaders.CHAT_TO</classname> that specifies to which user the Message should be sent to. To
create a message you might use the following Java code:
<programlisting language="java"><![CDATA[Message<String> xmppOutboundMsg = MessageBuilder.withPayload("Hello, XMPP!" )
.setHeader(XmppHeaders.CHAT_TO, "userhandle")
.build();]]></programlisting>
Another mechanism of setting such header is by using the XMPP enricher support. Here is an example using the enricher.
<programlisting language="xml"><![CDATA[<int-xmpp:header-enricher input-channel="input" output-channel="output">
<int-xmpp:chat-to value="test1@example.org"/>
</int-xmpp:header-enricher>]]></programlisting>
</para>
</section>
</section>
<section id="xmpp-presence">
<title>XMPP Presence</title>
<para>
XMPP also supports broadcasting state. You can use this capability to
let people who have you on their roster see your state changes. This happens all the time with your IM clients - you
change your away status, and then set an away message, and everybody who has you on their roster sees your icon or username change to reflect this new state, and
additionally might see your new "away" message.
If you would like to receive notification, or notify others, of state changes, you can use Spring Integration's "presence" adapters.
</para>
<section id="xmpp-roster-inbound-channel-adapter">
<title>Inbound Presence Message Channel Adapter</title>
<para>
Spring Integration provides an <emphasis>Inbound Presence Message Channel Adapter</emphasis> which supports receiving Presence (Roster)
events from other users in the system. To do this, the adapter "logs in" as a user
on your behalf, registers a <classname>RosterListener</classname> and forwards received Presence update events as Messages to the channel
identified by the <code>channel</code> attribute. The payload of the Message will be a <classname>org.jivesoftware.smack.packet.Presence</classname>
object (see http://www.igniterealtime.org/builds/smack/docs/3.1.0/javadoc/org/jivesoftware/smack/packet/Presence.html).
</para>
<para>
Configuration support for the XMPP <emphasis>Inbound Presence Message Channel Adapter</emphasis> is provided via
the <code>presence-inbound-channel-adapter</code> element.
<programlisting language="xml"><![CDATA[<int-xmpp:presence-inbound-channel-adapter channel="outChannel"
xmpp-connection="testConnection" auto-startup="false"/>]]></programlisting>
As you can see amongst the usual attributes this adapter also requires a reference to an XMPP Connection.
It is also important to mention that this adapter is an event driven adapter and a <classname>LifeCycle</classname> object.
It will register <classname>RosterListener</classname> when started and will unregister <classname>RosterListener</classname>
when stopped.
</para>
</section>
<section id="xmpp-roster-outbound-channel-adapter">
<title>Outbound Presence Message Channel Adapter</title>
<para>
Spring Integration also supports sending Presence (Roster) events to be seen by other users in the network. When you send a Message
to the <emphasis>Outbound Presence Message Channel Adapter</emphasis> it extracts the payload which is expected to be of
type <classname>org.jivesoftware.smack.packet.Presence</classname>
(see http://www.igniterealtime.org/builds/smack/docs/3.1.0/javadoc/org/jivesoftware/smack/packet/Presence.html) and sends it to
the XMPP Connection, thus advertising your presence events to the rest of the network.
</para>
<para>
Configuration support for the XMPP <emphasis>Outbound Presence Message Channel Adapter</emphasis> is provided via
the <code>presence-outbound-channel-adapter</code> element.
<programlisting language="xml"><![CDATA[<int-xmpp:presence-outbound-channel-adapter id="eventOutboundPresenceChannel"
xmpp-connection="testConnection"/>]]></programlisting>
It can also be a <emphasis>polling consumer</emphasis> (if it receives Messages from the Polling Channel) in which case you would
need to register a Poller.
<programlisting language="xml"><![CDATA[<int-xmpp:presence-outbound-channel-adapter id="pollingOutboundPresenceAdapter"
xmpp-connection="testConnection"
channel="pollingChannel">
<int:poller fixed-rate="1000" max-messages-per-poll="1"/>
</int-xmpp:presence-outbound-channel-adapter>]]></programlisting>
Similar to its Inbound counterpart it requires a reference to an XMPP Connection.
</para>
</section>
</section>
<section id="xmpp-appendices">
<title>Appendices</title>
<para>
Since Spring Integration XMPP support is based on Smack 3.1 API (http://www.igniterealtime.org/downloads/index.jsp), it is important
to know a few details related to more complex configuration of XMPP Connection object.
</para>
<para>
As it was said earlier the <code>xmpp-connection</code> namespace support is designed to simplify basic connection configuration and
only supports few configuration attributes. However, <classname>org.jivesoftware.smack.ConnectionConfiguration</classname> object defines about 20
attributes, and there is no real value of adding namespace support for all of them. So, for more complex connection configurations,
simply configure <classname>XmppConnectionFactoryBean</classname> as a regular bean injecting
<classname>org.jivesoftware.smack.ConnectionConfiguration</classname> as a constructor argument and configuring every property
you may need. This way SSL or any other attributes could be set directly in a consistent Spring way. Example:
<programlisting language="xml"><![CDATA[<bean id="xmppConnection" class="org.springframework.integration.xmpp.XmppConnectionFactoryBean">
<constructor-arg>
<bean class="org.jivesoftware.smack.ConnectionConfiguration">
<constructor-arg value="myServiceName"/>
<property name="truststorePath" value="..."/>
<property name="socketFactory" ref="..."/>
</bean>
</constructor-arg>
</bean>
<int:channel id="outboundEventChannel"/>
<int-xmpp:outbound-channel-adapter id="outboundEventAdapter"
channel="outboundEventChannel"
xmpp-connection="xmppConnection"/>]]></programlisting>
</para>
<para>
Another important aspect of Smack API is static initializers. For more complex cases (e.g., registering SASL Mechanism) you may need
to execute certain static initializers. One of those static initializers is <classname>SASLAuthentication</classname> which allows
you to register supported SASL mechanisms. For that level of complexity we would recommend Spring Javaconfig-style of XMPP Connection
configuration where you can configure the entire component through Java code and execute all other necessary Java code including
static initializers.
<programlisting language="java"><![CDATA[@Configuration
public class CustomConnectionConfiguration {
@Bean
public XmppConnection knight() {
SASLAuthentication.supportSASLMechanism("EXTERNAL", 0); // static initializer
ConnectionConfiguration config = new ConnectionConfiguration("localhost", 5223);
config.setTrustorePath("path_to_truststore.jks");
config.setSecurityEnabled(true);
config.setSocketFactory(SSLSocketFactory.getDefault());
conn = new XMPPConnection(config);
}
}]]></programlisting>
For more information on Javaconfig style of Application Context configuration refere to the following section in Spring Reference Manual
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
</para>
</section>
</chapter>