Major progress on Gradle port
Complete: -------- - src/* documentation resources moved to 'docs' subproject - docbook sources upgraded to Docbook 5 - formatted all docbook sources to strip tab characters and eliminate trailing whitespace - all projects compile and test successfully - all artifacts upload successfully to s3, static.sf.org, etc. Remaining: --------- - documentation L&F needs work. CSS, images, and highlighting aren't hooked up properly - spring-integration-jdbc codegen bits in Maven POM need to be transcribed into gradle - dependencies that were optional or provided scope in maven are currently 'compile' scope in Gradle. Need to figure out support in Gradle to fix this. - run through Eclipse classpath and project generation scenarios - delete all Maven artifacts
This commit is contained in:
442
docs/src/reference/docbook/xmpp.xml
Normal file
442
docs/src/reference/docbook/xmpp.xml
Normal file
@@ -0,0 +1,442 @@
|
||||
<?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>
|
||||
Spring Integration provides adapters for sending and receiving both XMPP messages and status changes from other
|
||||
entries in your roster as well as XMPP.
|
||||
</para>
|
||||
<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 instant 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.
|
||||
</para>
|
||||
<para>
|
||||
<!--
|
||||
todo do we have to include TM for 'Facebook', 'GMail', and 'Gtalk'?
|
||||
-->
|
||||
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>
|
||||
In XMPP,
|
||||
<emphasis>rosters</emphasis>
|
||||
(the roster corresponds to the notion of a "buddy list" in your typical IM client) are used to manage a list of
|
||||
other agents ("contacts", or "buddies", in an IM client)
|
||||
in the system, called<emphasis>roster items</emphasis>.
|
||||
The roster item contains - at a minimum - the roster item's JID which is its unique ID on the network.
|
||||
An actor may subscribe to the state changes of another actor in the system. The subscription can be bidirectional,
|
||||
as well.
|
||||
The subscription settings determine whose status updates are broadcast, and to whom.
|
||||
These subscriptions are stored on the XMPP server, and are thus durable.
|
||||
|
||||
</para>
|
||||
|
||||
|
||||
</section>
|
||||
<section id="xmpp-config">
|
||||
<title>Using The Spring Integration XMPP Namespace
|
||||
</title>
|
||||
<para>
|
||||
Using the Spring Integration XMPP namespace support is simple.
|
||||
|
||||
Its use is like any other module in the Spring framework: import the XML schema, and use it to define elements.
|
||||
|
||||
A prototypical XMPP-based integration might feature the following header. We won't repeat this in subsequent
|
||||
examples, because it is uninteresting.
|
||||
|
||||
|
||||
<programlisting lang="xml"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans:beans
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:p="http://www.springframework.org/schema/p"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xmpp="http://www.springframework.org/schema/integration/xmpp"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
xmlns:lang="http://www.springframework.org/schema/lang"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/integration/xmpp
|
||||
http://www.springframework.org/schema/integration/xmpp/spring-integration-xmpp.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
">
|
||||
...
|
||||
|
||||
</beans:beans>
|
||||
]]></programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
<section id="xmpp-connection">
|
||||
<title>XMPP Connection</title>
|
||||
<para>
|
||||
To participate in the network, an actor must connect to an XMPP server. Typically this requires - at a minimum - a
|
||||
<code>user</code>, a<code>password</code>, a<code>host</code>, and a<code>port</code>.
|
||||
|
||||
To create an XMPP connection, you may use the XML 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 Adapter</title>
|
||||
<para>The Spring Integration adapters support receiving messages from other users in the system. To do this, the
|
||||
adapter "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>
|
||||
- which is the type of the raw<code>
|
||||
Message</code>'s
|
||||
<code>body</code>
|
||||
property -
|
||||
depending on whether you specify
|
||||
<code>extract-payload</code>
|
||||
on the adapter's configuration or not.
|
||||
Inbound Messages are typically small and are text-oriented. Messages received using the adapter have
|
||||
a pretty standard layout, with known headers (all headers have keys defined on<classname>
|
||||
org.springframework.integration.xmpp.XmppHeaders</classname>):
|
||||
</para>
|
||||
|
||||
<table>
|
||||
<title>Header Values</title>
|
||||
|
||||
<tgroup cols="2">
|
||||
|
||||
<colspec colname="c1"/>
|
||||
<colspec colname="c2"/>
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Header Name</entry>
|
||||
<entry>What It Describes</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>XmppHeaders.TYPE</entry>
|
||||
<entry>The value of the
|
||||
the
|
||||
<code>
|
||||
org.jivesoftware.smack.packet.Message.Type
|
||||
</code>
|
||||
enum that describes the inbound message. Possible values are:
|
||||
<code>normal</code>,
|
||||
<code>chat</code>,
|
||||
<code>groupchat</code>,
|
||||
<code>headline</code>,
|
||||
<code>error</code>.
|
||||
</entry>
|
||||
|
||||
</row>
|
||||
<row>
|
||||
<entry>XmppHeaders.CHAT</entry>
|
||||
<entry>A reference to the
|
||||
<code>org.jivesoftware.smack.Chat</code>
|
||||
class which represents the
|
||||
threaded conversation containing the message.
|
||||
</entry>
|
||||
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<para>
|
||||
This adapter requires a reference to an XMPP Connection. You may
|
||||
use the
|
||||
<link linkend="xmpp-connection">xmpp-connection</link>
|
||||
element to define one.
|
||||
|
||||
An example might look as follows:
|
||||
|
||||
<programlisting lang="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans:beans ... >
|
||||
|
||||
<context:component-scan
|
||||
base-package="com.myxmppclient.inbound"/>
|
||||
|
||||
<context:property-placeholder
|
||||
location="#{ systemProperties['user.home'] }/xmpp/xmppclient.properties"/>
|
||||
|
||||
<channel id="xmppInbound"/>
|
||||
|
||||
<xmpp:xmpp-connection
|
||||
id="testConnection"
|
||||
...
|
||||
/> ]]>
|
||||
|
||||
<emphasis><![CDATA[<xmpp:message-inbound-channel-adapter
|
||||
channel="xmppInbound"
|
||||
xmpp-connection="testConnection"/>
|
||||
]]></emphasis><![CDATA[
|
||||
<service-activator input-channel="xmppInbound"
|
||||
ref="xmppMessageConsumer"/>
|
||||
|
||||
</beans:beans>]]></programlisting>
|
||||
|
||||
|
||||
</para>
|
||||
<para>
|
||||
In this example, the message is received from the XMPP adapter and passed to a
|
||||
<code>service-activator</code>
|
||||
component. Here's the declaration of the<code>service-activator</code>.
|
||||
<programlisting lang="java"><![CDATA[package com.myxmppclient.inbound ;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class XmppMessageConsumer {
|
||||
|
||||
@ServiceActivator
|
||||
public void consume(Message input) throws Throwable {
|
||||
String text = input.getBody();
|
||||
System.out.println( "Received message: " + text ) ;
|
||||
}
|
||||
|
||||
}
|
||||
]]></programlisting>
|
||||
</para>
|
||||
|
||||
</section>
|
||||
<section id="xmpp-message-outbound-channel-adapter">
|
||||
<title>Outbound Message Adapter</title>
|
||||
<para>
|
||||
You may also send messages to other users on XMPP using the
|
||||
<code>outbound-message-channel-adapter</code>
|
||||
adapter. The is configured like the
|
||||
|
||||
<link linkend="xmpp-message-inbound-channel-adapter">xmpp-message-inbound-channel-adapter</link>. The
|
||||
adapter takes an
|
||||
<code>xmpp-connection</code>
|
||||
reference.
|
||||
|
||||
|
||||
Here is a (necessarily) contrived example solution using the outbound adapter.
|
||||
|
||||
<programlisting lang="xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans:beans ... >
|
||||
|
||||
<context:component-scan
|
||||
base-package="com.myxmppproducer.outbound"/>
|
||||
|
||||
<context:property-placeholder
|
||||
location="#{ systemProperties['user.home'] }/xmpp/xmppclient.properties"/>
|
||||
|
||||
<beans:bean id="xmppProducer"
|
||||
class="com.myxmppproducer.outbound.XmppMessageProducer"
|
||||
p:recipient="${user.2.login}"/>
|
||||
|
||||
<poller default="true" fixed-rate="10000"/>
|
||||
|
||||
<xmpp:xmpp-connection
|
||||
id="testConnection"
|
||||
...
|
||||
/>
|
||||
|
||||
<inbound-channel-adapter ref="xmppProducer"
|
||||
channel="outboundChannel"/>
|
||||
|
||||
<channel id="outboundChannel"/>
|
||||
|
||||
<xmpp:message-outbound-channel-adapter
|
||||
channel="outboundChannel"
|
||||
xmpp-connection="testConnection"/>
|
||||
|
||||
</beans:beans>]]>
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
|
||||
The adapter expects as its input - at a minimum - a payload of type <classname>java.lang.String</classname>, and
|
||||
a header value
|
||||
for
|
||||
<code>XmppHeaders.CHAT_TO_USER</code>
|
||||
that specifies to which the user the payload body should be sent to.
|
||||
To create a message destined for the<code>outbound-message-channel-adapter</code>, you might use the following
|
||||
Java code:
|
||||
|
||||
<programlisting lang="java">
|
||||
<![CDATA[
|
||||
Message<String> xmppOutboundMsg = MessageBuilder.withPayload("Hello, world!" )
|
||||
.setHeader(XmppHeaders.CHAT_TO_USER, "userhandle")
|
||||
.build();
|
||||
]]></programlisting>
|
||||
|
||||
</para>
|
||||
<para>
|
||||
It's easy enough to use Java to update the <code>XmppHeaders.CHAT_TO_USER</code> header, and this has the advantage of dynamically updating the header at runtime in Java code.
|
||||
If, however, the target is more static in nature, you can
|
||||
configure it using the
|
||||
XMPP enricher support. Here is an example using the enricher. The enricher enriches the Spring Integration
|
||||
message
|
||||
to support the header values that the outbound XMPP adapters expect.
|
||||
<programlisting lang="xml">
|
||||
<![CDATA[
|
||||
<channel id="input"/>
|
||||
<channel id="output"/>
|
||||
|
||||
<xmpp:header-enricher input-channel="input" output-channel="output">
|
||||
<xmpp:message-to value="test1@example.org"/>
|
||||
</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> <para>
|
||||
The most important data for these adapters resides in the headers. The header keys are enumerated on
|
||||
the <code>org.springframework.integration.xmpp.XmppHeaders</code> class.
|
||||
|
||||
The header keys specific to these "presence" adapters start with the token "PRESENCE_".
|
||||
|
||||
Not all headers are available for both inbound and outbound.
|
||||
|
||||
</para> <table>
|
||||
<title>Header Values</title>
|
||||
|
||||
<tgroup cols="2">
|
||||
|
||||
<colspec colname="c1"/>
|
||||
<colspec colname="c2"/>
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Header Name</entry>
|
||||
<entry>What It Describes</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>XmppHeaders.PRESENCE_LANGUAGE</entry>
|
||||
<entry> The <code>java.lang.String</code> language in which the message was written.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>XmppHeaders.PRESENCE_PRIORITY</entry>
|
||||
<entry>
|
||||
The priority (int) of the message. Arbitrary, but it can be used to help assign relevance to a message which
|
||||
in turn might be used in its handling.
|
||||
</entry>
|
||||
|
||||
</row><row>
|
||||
<entry>XmppHeaders.PRESENCE_MODE</entry>
|
||||
<entry>
|
||||
An instance of the enum <code>org.jivesoftware.smack.packet.Presence.Mode</code> that has one of the following values:
|
||||
<code>chat,</code> <code>available,</code> <code>away,</code>
|
||||
<code>xa,</code> <code>dnd</code>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>XmppHeaders.PRESENCE_TYPE</entry>
|
||||
<entry>
|
||||
An instance of the enum <code>org.jivesoftware.smack.packet.Presence.Type</code>
|
||||
that has one of the following values:
|
||||
<code>available,</code> <code>unavailable,</code> <code>subscribe,</code> <code>subscribed,</code>
|
||||
<code>unsubscribe,</code> <code>unsubscribed,</code> and <code>error</code>.
|
||||
|
||||
|
||||
</entry>
|
||||
</row> <row>
|
||||
<entry>XmppHeaders.PRESENCE_STATUS</entry>
|
||||
<entry>
|
||||
A <code>java.lang.String</code> string representing the status of the agent. This corresponds to an agents "away" message.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>XmppHeaders.PRESENCE_FROM</entry>
|
||||
<entry>
|
||||
A <code>java.lang.String</code> string representing the handle of the user whose state is being received.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
|
||||
</tbody>
|
||||
</tgroup>
|
||||
|
||||
</table>
|
||||
<section id="xmpp-presence-inbound-channel-adapter">
|
||||
<title>Inbound Presence Adapter</title>
|
||||
<para>
|
||||
The first adapter supports receiving messages whenever an agent on your roster has updated its
|
||||
state. Most of the important data comes in through the headers.
|
||||
|
||||
</para>
|
||||
</section>
|
||||
<section id="xmpp-presence-outbound-channel-adapter">
|
||||
<title>Outbound Presence Adapter</title>
|
||||
<para>TBD</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<!--<section id="xmpp-samples">
|
||||
<title>XMPP Samples</title>
|
||||
<para>
|
||||
We really should have some samples...
|
||||
</para>
|
||||
</section>
|
||||
-->
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user