From 06831b9e22e4e48a1532f67f7df49df59be5d73a Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Tue, 15 Jan 2013 17:46:21 -0500 Subject: [PATCH] INT-2882 Upgrade DocBook Reference Plugin to 0.2.6 For reference see: https://jira.springsource.org/browse/INT-2882 * Verify spacing * Ensure all source code samples are typed: e.g. * Ensure source code fits space in PDF format --- build.gradle | 2 +- src/reference/docbook/aggregator.xml | 80 +++-- src/reference/docbook/bridge.xml | 8 +- src/reference/docbook/chain.xml | 50 +-- src/reference/docbook/channel-adapter.xml | 6 +- src/reference/docbook/channel.xml | 29 +- src/reference/docbook/configuration.xml | 94 +++--- src/reference/docbook/control-bus.xml | 4 +- src/reference/docbook/delayer.xml | 45 +-- src/reference/docbook/endpoint.xml | 62 ++-- src/reference/docbook/file.xml | 88 ++--- src/reference/docbook/filter.xml | 92 +++--- src/reference/docbook/ftp.xml | 310 +++++++++--------- src/reference/docbook/gateway.xml | 42 ++- src/reference/docbook/gemfire.xml | 165 +++++----- src/reference/docbook/handler-advice.xml | 166 +++++----- src/reference/docbook/http.xml | 123 ++++--- src/reference/docbook/ip.xml | 304 +++++++++--------- src/reference/docbook/jdbc.xml | 20 +- src/reference/docbook/jms.xml | 94 +++--- src/reference/docbook/jmx.xml | 10 +- src/reference/docbook/jpa.xml | 220 +++++++------ src/reference/docbook/mail.xml | 196 ++++++------ src/reference/docbook/message-publishing.xml | 2 +- src/reference/docbook/message-store.xml | 32 +- src/reference/docbook/mongodb.xml | 68 ++-- src/reference/docbook/redis.xml | 195 ++++++------ src/reference/docbook/rmi.xml | 38 ++- src/reference/docbook/samples.xml | 319 +++++++++---------- src/reference/docbook/service-activator.xml | 26 +- src/reference/docbook/sftp.xml | 3 +- src/reference/docbook/splitter.xml | 24 +- src/reference/docbook/stream.xml | 14 +- src/reference/docbook/transactions.xml | 40 +-- src/reference/docbook/transformer.xml | 57 ++-- src/reference/docbook/twitter.xml | 179 +++++------ src/reference/docbook/ws.xml | 6 +- src/reference/docbook/xml.xml | 12 +- src/reference/docbook/xmpp.xml | 182 ++++++----- 39 files changed, 1666 insertions(+), 1741 deletions(-) diff --git a/build.gradle b/build.gradle index 9f376bc0e1..5a286c0491 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { maven { url 'http://repo.springsource.org/plugins-release' } } dependencies { - classpath 'org.springframework.build.gradle:docbook-reference-plugin:0.1.6' + classpath 'org.springframework.build.gradle:docbook-reference-plugin:0.2.6' } } diff --git a/src/reference/docbook/aggregator.xml b/src/reference/docbook/aggregator.xml index 3fa4208f78..f555908915 100644 --- a/src/reference/docbook/aggregator.xml +++ b/src/reference/docbook/aggregator.xml @@ -117,7 +117,7 @@ // default implementation exists } - protected abstract Object aggregatePayloads(MessageGroup group, Map defaultHeaders); + protected abstract Object aggregatePayloads(MessageGroup group, Map defaultHeaders); }]]> @@ -127,16 +127,14 @@ and it has a default value based on the MessageHeaders.CORRELATION_ID message header: - + this.releaseStrategy = releaseStrategy == null ? new SequenceSizeReleaseStrategy() : releaseStrategy; + ... +}]]> As for actual processing of the message group, the default implementation is the DefaultAggregatingMessageGroupProcessor. It creates a @@ -331,8 +329,7 @@ then you should simply provide an implementation of the ReleaseStrate XML through the <aggregator/> element. Below you can see an example of an aggregator. - - + ReleaseStrate expire-groups-upon-completion="false" ]]> ]]> @@ -598,22 +594,22 @@ then you should simply provide an implementation of the ReleaseStrate strategy will assemble all aggregated messages in the List. So now we have two problems. First we need to extract individual messages from the list, and then we need to extract the payload of each message and assemble the array of objects (see code below). - + > messages){ - List stringList = new ArrayList(); - for (Message message : messages) { - stringList.add(message.getPayload()); - } - return stringList.toArray(new String[]{}); + List stringList = new ArrayList(); + for (Message message : messages) { + stringList.add(message.getPayload()); + } + return stringList.toArray(new String[]{}); }]]> - + However, with SpEL such a requirement could actually be handled relatively easily with a one-line expression, thus sparing you from writing a custom class and configuring it as a bean. - + ]]> - + output-channel="replyChannel" + expression="#this.![payload].toArray()"/>]]> + In the above configuration we are using a Collection Projection expression to assemble a new collection from the payloads of all messages in the list and then transforming it to an Array, thus @@ -726,28 +722,28 @@ then you should simply provide an implementation of the ReleaseStrate MessageGroupStore. - message); + MessageGroup addMessageToGroup(Object groupId, Message message); - MessageGroup markMessageGroup(MessageGroup group); + MessageGroup markMessageGroup(MessageGroup group); - MessageGroup removeMessageFromGroup(Object key, Message messageToRemove); + MessageGroup removeMessageFromGroup(Object key, Message messageToRemove); - MessageGroup markMessageFromGroup(Object key, Message messageToMark); + MessageGroup markMessageFromGroup(Object key, Message messageToMark); - void removeMessageGroup(Object groupId); + void removeMessageGroup(Object groupId); - void registerMessageGroupExpiryCallback(MessageGroupCallback callback); + void registerMessageGroupExpiryCallback(MessageGroupCallback callback); - int expireMessageGroups(long timeout); + int expireMessageGroups(long timeout); }]]> For more information please refer to the @@ -763,9 +759,9 @@ then you should simply provide an implementation of the ReleaseStrate callbacks to apply to its MessageGroups when they expire. The interface is very straightforward: - @@ -787,13 +783,13 @@ then you should simply provide an implementation of the ReleaseStrate for the message expiry in the form of a MessageGroupStoreReaper: - - - + + + - + ]]> The reaper is a Runnable, and all that is happening diff --git a/src/reference/docbook/bridge.xml b/src/reference/docbook/bridge.xml index f3ea04ba89..b2b68346e9 100644 --- a/src/reference/docbook/bridge.xml +++ b/src/reference/docbook/bridge.xml @@ -17,7 +17,7 @@ poller's "maxMessagesPerPoll" property will enforce a limit on the throughput. - Another valid use for a Messaging Bridge is to connect two different systems. In such a scenario, Spring + Another valid use for a Messaging Bridge is to connect two different systems. In such a scenario, Spring Integration's role would be limited to making the connection between these systems and managing a poller if necessary. It is probably more common to have at least a Transformer between the two systems to translate between their formats, and in that case, the channels would be provided as the @@ -31,18 +31,18 @@ The <bridge> element is used to create a Messaging Bridge between two Message Channels or Channel Adapters. Simply provide the "input-channel" and "output-channel" attributes: - ]]> + ]]> As mentioned above, a common use case for the Messaging Bridge is to connect a PollableChannel to a SubscribableChannel, and when performing this role, the Messaging Bridge may also serve as a throttler: - + ]]> Connecting Channel Adapters is just as easy. Here is a simple echo example between the "stdin" and "stdout" adapters from Spring Integration's "stream" namespace. - + diff --git a/src/reference/docbook/chain.xml b/src/reference/docbook/chain.xml index 06a1886a0b..d5768cd2bd 100644 --- a/src/reference/docbook/chain.xml +++ b/src/reference/docbook/chain.xml @@ -58,13 +58,13 @@ The <chain> element provides an input-channel attribute, and if the last element in the chain is capable of producing reply messages (optional), it also supports an output-channel attribute. The sub-elements are then filters, transformers, splitters, and service-activators. The last element may also be a router or an outbound-channel-adapter. - - - - - - - ]]> + + + + + + +]]> The <header-enricher> element used in the above example will set a message header named "foo" with a value @@ -75,14 +75,14 @@ The <chain> can be configured as the last 'black-box' consumer of the message flow. For this solution it is enough to put at the end of the <chain> some <outbound-channel-adapter>: - - - - - - - - ]]> + + + + + + + +]]> Disallowed Attributes and Elements @@ -130,7 +130,7 @@ To accomplish this you can utilize a Messaging Gateway by including a <gateway> element. For example: - + @@ -138,26 +138,26 @@   - + - + - +   - + - + - + - + - + - ]]> +]]> In the above example the nested-chain-a will be called at the end of main-chain processing by the 'gateway' element configured there. While in diff --git a/src/reference/docbook/channel-adapter.xml b/src/reference/docbook/channel-adapter.xml index f76908bbeb..5913e823b9 100644 --- a/src/reference/docbook/channel-adapter.xml +++ b/src/reference/docbook/channel-adapter.xml @@ -92,8 +92,7 @@ If the channel being adapted is a PollableChannel, provide a poller sub-element: - ]]> -]]>]]> @@ -105,8 +104,7 @@ is only referenced by a single definition of the <outbound-channel-adapter>, you can define it as inner bean: - - ]]> ]]> diff --git a/src/reference/docbook/channel.xml b/src/reference/docbook/channel.xml index d3a7cca06e..5340954496 100644 --- a/src/reference/docbook/channel.xml +++ b/src/reference/docbook/channel.xml @@ -241,18 +241,17 @@ Scoped Channel Spring Integration 1.0 provided a ThreadLocalChannel implementation, but that has been removed as of 2.0. Now, there is a more general way for handling the same requirement by simply adding a "scope" attribute to a channel. The value of the attribute can be any name of a Scope that is available within the context. For example, in a web environment, certain Scopes are available, and any custom Scope implementations can be registered with the context. Here's an example of a ThreadLocal-based scope being applied to a channel, including the registration of the Scope itself. - + - + - + - - - - - -]]> + + + + +]]> The channel above also delegates to a queue internally, but the channel is bound to the current thread, so the contents of the queue are as well. That way the thread that @@ -707,13 +706,13 @@ payload to an Integer. As mentioned above, Spring Integration provides a simple Wire Tap interceptor out of the box. You can configure a Wire Tap on any channel within an <interceptors/> element. This is especially useful for debugging, and can be used in conjunction with Spring Integration's logging - Channel Adapter as follows: - - - - + Channel Adapter as follows: + + + + - ]]> +]]> The 'logging-channel-adapter' also accepts an 'expression' attribute so that you can evaluate a SpEL expression against 'payload' and/or 'headers' variables. Alternatively, to simply log diff --git a/src/reference/docbook/configuration.xml b/src/reference/docbook/configuration.xml index a9df30a51b..afb41ce44a 100644 --- a/src/reference/docbook/configuration.xml +++ b/src/reference/docbook/configuration.xml @@ -61,31 +61,33 @@ File, etc.) that provides namespace support defines its elements within a separate schema. In order to use these elements, simply add the necessary namespaces with an "xmlns" entry and the corresponding "schemaLocation" mapping. For example, the following root element shows several of these namespace declarations: + + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:int="http://www.springframework.org/schema/integration" + xmlns:int-file="http://www.springframework.org/schema/integration/file" + xmlns:int-jms="http://www.springframework.org/schema/integration/jms" + xmlns:int-mail="http://www.springframework.org/schema/integration/mail" + xmlns:int-rmi="http://www.springframework.org/schema/integration/rmi" + xmlns:int-ws="http://www.springframework.org/schema/integration/ws" + xsi:schemaLocation="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/integration/file + http://www.springframework.org/schema/integration/file/spring-integration-file.xsd + http://www.springframework.org/schema/integration/jms + http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd + http://www.springframework.org/schema/integration/mail + http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd + http://www.springframework.org/schema/integration/rmi + http://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd + http://www.springframework.org/schema/integration/ws + http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd"> ... ]]> + The reference manual provides specific examples of the various elements in their corresponding chapters. Here, the main thing to recognize is the consistency of the naming for each namespace URI and schema location. @@ -94,11 +96,11 @@
Configuring the Task Scheduler - + In Spring Integration, the ApplicationContext plays the central role of a Message Bus, and there are only a couple configuration options to consider. First, you may want to control the central TaskScheduler instance. You can do so by providing a single bean with the name "taskScheduler". This is also defined as a constant: - + By default Spring Integration relies on an instance of ThreadPoolTaskScheduler as described in the Task Execution and Scheduling section of the Spring Framework reference manual. That default TaskScheduler will startup automatically with a pool of 10 threads. If you provide your own TaskScheduler instance instead, you can set the 'autoStartup' property @@ -120,9 +122,9 @@ as described here, instead of the default taskScheduler. To do that, simply define a bean with the appropriate JNDI name for your environment, for example: - - - + + + ]]> @@ -169,9 +171,9 @@ Whenever relying on Spring Integration's XML namespace support, a default "errorChannel" bean will be created behind the scenes. However, you can just as easily define your own if you want to control the settings. - - - ]]> + + +]]> The default "errorChannel" is a PublishSubscribeChannel. @@ -197,17 +199,17 @@
Annotation Support - In addition to the XML namespace support for configuring Message Endpoints, - it is also possible to use annotations. First, Spring Integration provides - the class-level @MessageEndpoint as a - stereotype annotation, meaning that it is itself - annotated with Spring's @Component annotation - and is therefore recognized automatically as a bean definition when using + In addition to the XML namespace support for configuring Message Endpoints, + it is also possible to use annotations. First, Spring Integration provides + the class-level @MessageEndpoint as a + stereotype annotation, meaning that it is itself + annotated with Spring's @Component annotation + and is therefore recognized automatically as a bean definition when using Spring component-scanning. - Even more important are the various method-level annotations that indicate - the annotated method is capable of handling a message. The following example + Even more important are the various method-level annotations that indicate + the annotated method is capable of handling a message. The following example demonstrates both: @MessageEndpoint public class FooService { @@ -219,7 +221,7 @@ public class FooService { } - Exactly what it means for the method to "handle" the Message depends on the + Exactly what it means for the method to "handle" the Message depends on the particular annotation. Annotations available in Spring Integration include: @Aggregator @@ -233,16 +235,16 @@ public class FooService { The behavior of each is described in its own chapter or section within this reference. - If you are using XML configuration in combination with annotations, the - @MessageEndpoint annotation is not required. - If you want to configure a POJO reference from the "ref" attribute of a - <service-activator/> element, it is sufficient to provide the - method-level annotations. In that case, the annotation prevents ambiguity + If you are using XML configuration in combination with annotations, the + @MessageEndpoint annotation is not required. + If you want to configure a POJO reference from the "ref" attribute of a + <service-activator/> element, it is sufficient to provide the + method-level annotations. In that case, the annotation prevents ambiguity even when no "method" attribute exists on the <service-activator/> element. - In most cases, the annotated handler method should not require the - Message type as its parameter. Instead, the method + In most cases, the annotated handler method should not require the + Message type as its parameter. Instead, the method parameter type can match the message's payload type. public class FooService { @@ -311,7 +313,7 @@ public class FooService { to use XML for the endpoints, since it is easier to keep track of the overall configuration in a single, external location (and besides the namespace-based XML configuration is not very verbose). If you do prefer to provide channels with the annotations however, you just need to enable a SI Annotations BeanPostProcessor. The following element should - be added: ]]> + be added: ]]> When configuring the "inputChannel" and "outputChannel" with annotations, the "inputChannel" must be a reference to a SubscribableChannel instance. diff --git a/src/reference/docbook/control-bus.xml b/src/reference/docbook/control-bus.xml index 5d2b5c0098..59e7ba5828 100644 --- a/src/reference/docbook/control-bus.xml +++ b/src/reference/docbook/control-bus.xml @@ -37,8 +37,8 @@ For example, to execute a method on a Spring Bean a client could send a message to the operation channel as follows: - Message operation = MessageBuilder.withPayload("@myServiceBean.shutdown()").build(); -operationChannel.send(operation) + The root of the context for the expression is the Message itself, so you also have access to the 'payload' diff --git a/src/reference/docbook/delayer.xml b/src/reference/docbook/delayer.xml index 50091fb595..c750983211 100644 --- a/src/reference/docbook/delayer.xml +++ b/src/reference/docbook/delayer.xml @@ -24,11 +24,12 @@ but the delayer also has 'default-delay' and 'delay-header-name' attributes that are used to determine the number of milliseconds that each Message should be delayed. The following delays all messages by 3 seconds: - ]]> + ]]> If you need per-Message determination of the delay, then you can also provide the name of a header using the 'delay-header-name' attribute: - ]]> + ]]> In the example above the 3 second delay would only apply in the case that the header value is not present for a given inbound Message. If you only want to apply a delay to Messages that have an explicit header value, then you can set the 'default-delay' to 0 or don't use it at all (by default it is 0). @@ -53,11 +54,11 @@ provided by Spring Integration on startup: . If you want to delegate to a different scheduler, you can provide a reference through the delayer element's 'scheduler' attribute: - + - ]]> +]]> If you configure an external ThreadPoolTaskScheduler you can set on this scheduler property waitForTasksToCompleteOnShutdown = true. @@ -104,18 +105,18 @@ Message will remain in the persistent MessageStore. You can use any custom org.aopalliance.aop.Advice implementation within the <advice-chain>. A sample configuration of the <delayer> may look like this: - - - - - - - - - - ]]> + + + + + + + + + +]]> The DelayHandler can be exported as a JMX MBean @@ -123,9 +124,9 @@ which allows the rescheduling of delayed persisted Messages at runtime, for example, if the TaskScheduler has previously been stopped. These operations can be invoked via a Control Bus command: - delayerReschedulingMessage = - MessageBuilder.withPayload("@'delayer.handler'.reschedulePersistedMessages()").build(); - controlBusChannel.send(delayerReschedulingMessage);]]> + delayerReschedulingMessage = + MessageBuilder.withPayload("@'delayer.handler'.reschedulePersistedMessages()").build(); + controlBusChannel.send(delayerReschedulingMessage);]]> For more information regarding the Message Store, JMX and the Control Bus, please read . diff --git a/src/reference/docbook/endpoint.xml b/src/reference/docbook/endpoint.xml index 8f44e4dae5..e1dbb9ca50 100644 --- a/src/reference/docbook/endpoint.xml +++ b/src/reference/docbook/endpoint.xml @@ -372,20 +372,20 @@ consumer.setTaskExecutor(taskExecutor); For example, a simple interval-based poller with a 1-second interval would be - configured like this: - + configured like this: + ]]> As an alternative to fixed-rate you can also use the fixed-delay attribute. For a poller based on a Cron expression, use the cron attribute instead: - - - ]]> + + +]]> If the input channel is a PollableChannel, then the poller configuration is @@ -398,13 +398,13 @@ consumer.setTaskExecutor(taskExecutor); It is also possible to create top-level pollers in which case only a ref is required: - + - + - ]]> +]]> @@ -423,12 +423,12 @@ consumer.setTaskExecutor(taskExecutor); endpoint with a PollableChannel for its input-channel that is defined within the same ApplicationContext and has no explicitly configured poller sub-element will use that default. - + - - ]]> + +]]> Transaction Support @@ -491,12 +491,12 @@ any transaction configuration essentially allowing you to enhance the behavior o (the other major factor being the expected volume on the channel to which the endpoint subscribes). To enable concurrency for a polling endpoint that is configured with the XML namespace support, provide the task-executor reference on its <poller/> element and then provide one or more of the properties shown below: - + - ]]> +]]> If no task-executor is provided, the consumer's handler will be invoked in the caller's thread. Note that the caller is usually the default TaskScheduler (see ). Also, keep in mind that the task-executor attribute can @@ -513,11 +513,11 @@ any transaction configuration essentially allowing you to enhance the behavior o hand when using Spring Integration's own queue-based channels, the timeout value does have a chance to participate. The following example demonstrates how a Polling Consumer will receive Messages nearly instantaneously. - - + + - ]]> +]]> Using this approach does not carry much overhead since internally it is nothing more then a timed-wait thread which does not require nearly as much CPU resource usage as a thrashing, infinite while loop for example. @@ -593,13 +593,13 @@ any transaction configuration essentially allowing you to enhance the behavior o To register a Converter all you need is to implement org.springframework.core.convert.converter.Converter and define it via convenient namespace support: - + ]]> or as an inner bean: - - + + ]]> diff --git a/src/reference/docbook/file.xml b/src/reference/docbook/file.xml index c2e9c5e533..a3425acaae 100644 --- a/src/reference/docbook/file.xml +++ b/src/reference/docbook/file.xml @@ -27,8 +27,8 @@ A FileReadingMessageSource can be used to consume files from the filesystem. This is an implementation of MessageSource that creates messages from a file system directory. ]]> + class="org.springframework.integration.file.FileReadingMessageSource" + p:inputDirectory="${input.directory}"/>]]> To prevent creating messages for certain files, you may supply a @@ -36,9 +36,9 @@ AcceptOnceFileListFilter is used. This filter ensures files are picked up only once from the directory. ]]> + class="org.springframework.integration.file.FileReadingMessageSource" + p:inputDirectory="${input.directory}" + p:filter-ref="customFilterBean"/>]]> A common problem with reading files is that a file may be detected before @@ -51,19 +51,19 @@ The CompositeFileListFilter enables the composition. + class="org.springframework.integration.file.FileReadingMessageSource" + p:inputDirectory="${input.directory}" + p:filter-ref="compositeFilter"/> - - - - - - - - + class="org.springframework.integration.file.filters.CompositeFileListFilter"> + + + + + + + + ]]> @@ -85,20 +85,20 @@ Within this namespace you can reduce the FileReadingMessageSource and wrap it in an inbound Channel Adapter like this: - + - + - + - ]]> +]]> The first channel adapter is relying on the default filter that just prevents @@ -117,17 +117,17 @@ them from being picked up concurrently. To do this you can use a FileLocker. There is a java.nio based implementation available out of the box, but it is also possible to implement your own locking scheme. The nio locker can be injected as follows - - - ]]> + + +]]> A custom locker you can configure like this: - - - ]]> + + +]]> When a file inbound adapter is configured with a locker, it will take the responsibility to acquire a @@ -143,8 +143,8 @@ that Spring Integration uses internally to wire FileListFilters FileLocker to the FileReadingMessageSource. A custom DirectoryScanner can be injected into the <int-file:inbound-channel-adapter/> on the scanner attribute. - ]]> + ]]> This gives you full freedom to choose the ordering, listing and locking strategies. @@ -355,13 +355,13 @@
File Outbound Channel Adapter - ]]> + ]]> The namespace based configuration also supports a delete-source-files attribute. If set to true, it will trigger the deletion of the original source files after writing to a destination. The default value for that flag is false. - ]]> @@ -436,11 +436,11 @@ To configure File specific transformers you can use the appropriate elements from the file namespace. - + - ]]> +]]> The delete-files option signals to the transformer that it should delete diff --git a/src/reference/docbook/filter.xml b/src/reference/docbook/filter.xml index 3d126f15e8..502a717d37 100644 --- a/src/reference/docbook/filter.xml +++ b/src/reference/docbook/filter.xml @@ -19,13 +19,13 @@ In Spring Integration, a Message Filter may be configured as a Message Endpoint that delegates to an implementation of the MessageSelector interface. That interface is itself quite - simple: message); + boolean accept(Message message); - }]]> +}]]> The MessageFilter constructor accepts a selector instance: - + In combination with the namespace and SpEL, very powerful filters can be configured with very little java code.
@@ -37,34 +37,34 @@ The <filter> element is used to create a Message-selecting endpoint. In addition to "input-channel - and output-channel attributes, it requires a ref. The ref may point to a + and output-channel attributes, it requires a ref. The ref may point to a MessageSelector implementation: - + - ]]> +]]> Alternatively, the method attribute can be added at which point the ref may refer to any object. The referenced method may expect either the Message type or the payload type of inbound Messages. The method must return a boolean value. If the method returns 'true', the Message will be sent to the output-channel. - + - ]]> +]]> If the selector or adapted POJO method returns false, there are a few settings that control the handling of the rejected Message. By default (if configured like the example above), rejected Messages will be silently dropped. If rejection should instead result in an error condition, then set the throw-exception-on-rejection attribute to true: - ]]> + ]]> - + If you want rejected messages to be routed to a specific channel, provide that reference as the discard-channel: - ]]> + ]]> Message Filters are commonly used in conjunction with a Publish Subscribe Channel. Many filter endpoints may @@ -96,11 +96,11 @@ The string passed as the expression attribute will be evaluated as a SpEL expression with the Message available in the evaluation context. If it is necessary to include the result of an expression in the scope of the application context you can use the - #{} notation as defined in the + #{} notation as defined in the SpEL reference documentation . - ]]> @@ -112,59 +112,57 @@ had been modified. If the ExpressionSource bean is named "expressionSource", then it is not necessary to provide the source attribute on the <expression> element, but in this case it's shown for completeness. - - + + - - - - + + + + ]]> Then, the 'config/integration/expressions.properties' file (or any more specific version with a locale extension to be resolved in the typical way that resource-bundles are loaded) would contain a key/value pair: - 100]]> + 100]]> - All of these examples that use expression as an attribute - or sub-element can also be applied within transformer, router, splitter, + All of these examples that use expression as an attribute + or sub-element can also be applied within transformer, router, splitter, service-activator, and header-enricher elements. Of course, the semantics/role - of the given component type would affect the interpretation of the evaluation - result in the same way that the return value of a method-invocation would - be interpreted. For example, an expression can return Strings that are to - be treated as Message Channel names by a router component. However, the - underlying functionality of evaluating the expression against the Message + of the given component type would affect the interpretation of the evaluation + result in the same way that the return value of a method-invocation would + be interpreted. For example, an expression can return Strings that are to + be treated as Message Channel names by a router component. However, the + underlying functionality of evaluating the expression against the Message as the root object, and resolving bean names if prefixed with '@' is consistent across all of the core EIP components within Spring Integration.
Configuring a Filter with Annotations - A filter configured using annotations would look like this. - - - + A filter configured using annotations would look like this. + + + An annotation indicating that this method shall be used as a filter. Must be specified if this class will be used as a filter. - + All of the configuration options provided by the xml element are also available for the @Filter annotation. - + The filter can be either referenced explicitly from XML or, if - the @MessageEndpoint annotation is defined + the @MessageEndpoint annotation is defined on the class, detected automatically through classpath scanning.
diff --git a/src/reference/docbook/ftp.xml b/src/reference/docbook/ftp.xml index c93b32b2dc..aedbae2639 100644 --- a/src/reference/docbook/ftp.xml +++ b/src/reference/docbook/ftp.xml @@ -11,12 +11,12 @@ The File Transfer Protocol (FTP) is a simple network protocol which allows you to transfer files between two computers on the Internet. - There are two actors when it comes to FTP communication: client and server. - To transfer files with FTP/FTPS, you use a client which initiates a connection to a remote computer - that is running an FTP server. After the connection is established, the client can choose - to send and/or receive copies of files. + There are two actors when it comes to FTP communication: client and server. + To transfer files with FTP/FTPS, you use a client which initiates a connection to a remote computer + that is running an FTP server. After the connection is established, the client can choose + to send and/or receive copies of files. - + Spring Integration supports sending and receiving files over FTP/FTPS by providing three client side endpoints: Inbound Channel Adapter, Outbound Channel Adapter, and @@ -26,153 +26,153 @@ To use the FTP namespace, add the following to the header of your XML file: - - + +
FTP Session Factory - Before configuring FTP adapters you must configure an FTP Session Factory. You can configure + Before configuring FTP adapters you must configure an FTP Session Factory. You can configure the FTP Session Factory with a regular bean definition where the implementation class is org.springframework.integration.ftp.session.DefaultFtpSessionFactory: Below is a basic configuration: - - - - - - - - - + + + + + + + + + ]]> For FTPS connections all you need to do is use org.springframework.integration.ftp.session.DefaultFtpsSessionFactory instead. Below is the complete configuration sample: - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + ]]> - Every time an adapter requests a session object from its SessionFactory the session is - returned from a session pool maintained by a caching wrapper around the factory. A Session in the session pool might go stale - (if it has been disconnected by the server due to inactivity) so the SessionFactory + Every time an adapter requests a session object from its SessionFactory the session is + returned from a session pool maintained by a caching wrapper around the factory. A Session in the session pool might go stale + (if it has been disconnected by the server due to inactivity) so the SessionFactory will perform validation to make sure that it never returns a stale session to the adapter. If a stale session was encountered, it will be removed from the pool, and a new one will be created. - If you experience connectivity problems and would like to trace Session creation as well as see which Sessions are + If you experience connectivity problems and would like to trace Session creation as well as see which Sessions are polled you may enable it by setting the logger to TRACE level (e.g., log4j.category.org.springframework.integration.file=TRACE) - Now all you need to do is inject these session factories into your adapters. Obviously the protocol (FTP or FTPS) that an adapter will + Now all you need to do is inject these session factories into your adapters. Obviously the protocol (FTP or FTPS) that an adapter will use depends on the type of session factory that has been injected into the adapter. - A more practical way to provide values for FTP/FTPS Session Factories is by using Spring's property + A more practical way to provide values for FTP/FTPS Session Factories is by using Spring's property placeholder support (See: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-placeholderconfigurer). - + Advanced Configuration - + - DefaultFtpSessionFactory provides an abstraction over the underlying client API which, in the current release of - Spring Integration, is Apache Commons Net. This spares you from the low level configuration details - of the org.apache.commons.net.ftp.FTPClient. However there are times when access to lower level FTPClient details is - necessary to achieve more advanced configuration (e.g., setting data timeout, default timeout etc.). For that purpose, AbstractFtpSessionFactory + DefaultFtpSessionFactory provides an abstraction over the underlying client API which, in the current release of + Spring Integration, is Apache Commons Net. This spares you from the low level configuration details + of the org.apache.commons.net.ftp.FTPClient. However there are times when access to lower level FTPClient details is + necessary to achieve more advanced configuration (e.g., setting data timeout, default timeout etc.). For that purpose, AbstractFtpSessionFactory (the base class for all FTP Session Factories) exposes hooks, in the form of the two post-processing methods below. - As you can see, there is no default implementation for these two methods. However, by extending DefaultFtpSessionFactory you can override these methods + * Will handle additional initialization after client.connect() method was invoked, + * but before any action on the client has been taken + */ +protected void postProcessClientAfterConnect(T t) throws IOException { + // NOOP +} +/** + * Will handle additional initialization before client.connect() method was invoked. + */ +protected void postProcessClientBeforeConnect(T client) throws IOException { + // NOOP +}]]> + As you can see, there is no default implementation for these two methods. However, by extending DefaultFtpSessionFactory you can override these methods to provide more advanced configuration of the FTPClient. For example:
- +
FTP Inbound Channel Adapter - The FTP Inbound Channel Adapter is a special listener that will connect to the FTP server and will listen + The FTP Inbound Channel Adapter is a special listener that will connect to the FTP server and will listen for the remote directory events (e.g., new file created) at which point it will initiate a file transfer. - + - + channel="ftpChannel" + session-factory="ftpSessionFactory" + charset="UTF-8" + auto-create-local-directory="true" + delete-remote-files="true" + filename-pattern="*.txt" + remote-directory="some/remote/path" + remote-file-separator="/" + local-filename-generator-expression="#this.toUpperCase() + '.a'" + local-directory="."> + ]]> - As you can see from the configuration above you can configure an FTP Inbound Channel Adapter via the inbound-channel-adapter - element while also providing values for various attributes such as local-directory, filename-pattern + As you can see from the configuration above you can configure an FTP Inbound Channel Adapter via the inbound-channel-adapter + element while also providing values for various attributes such as local-directory, filename-pattern (which is based on simple pattern matching, not regular expressions), and of course the reference to a session-factory. - By default the transferred file will carry the same name as the original file. If you want to override this behavior you - can set the local-filename-generator-expression attribute which allows you to provide a SpEL Expression to generate - the name of the local file. Unlike outbound gateways and adapters where the root object of the SpEL Evaluation Context + By default the transferred file will carry the same name as the original file. If you want to override this behavior you + can set the local-filename-generator-expression attribute which allows you to provide a SpEL Expression to generate + the name of the local file. Unlike outbound gateways and adapters where the root object of the SpEL Evaluation Context is a Message, this inbound adapter does not yet have the Message at the time of evaluation since that's what it ultimately generates with the transferred file as its payload. So, the root object of the SpEL Evaluation Context is the original name of the remote file (String). - + Sometimes file filtering based on the simple pattern specified via filename-pattern attribute might not be - sufficient. If this is the case, you can use the filename-regex attribute to specify a Regular Expression + sufficient. If this is the case, you can use the filename-regex attribute to specify a Regular Expression (e.g. filename-regex=".*\.test$"). And of course if you need complete control you can use filter - attribute and provide a reference to any custom implementation of the + attribute and provide a reference to any custom implementation of the org.springframework.integration.file.filters.FileListFilter, a strategy interface for filtering a list of files. @@ -181,12 +181,12 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/ftp file separator character to use if the default '/' is not applicable for your particular environment. - Please refer to the schema for more details on these attributes. + Please refer to the schema for more details on these attributes. - It is also important to understand that the FTP Inbound Channel Adapter is a Polling Consumer and + It is also important to understand that the FTP Inbound Channel Adapter is a Polling Consumer and therefore you must configure a poller (either via a global default or a local sub-element). - Once a file has been transferred, a Message with a java.io.File as its payload will be generated and sent to the channel + Once a file has been transferred, a Message with a java.io.File as its payload will be generated and sent to the channel identified by the channel attribute. @@ -198,18 +198,17 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/ftp As a user in most cases you are only interested in files that are complete and would like to filter only files that are complete. To handle these scenarios you can use the filtering support provided by the filename-pattern, filename-regex and filter attributes. Here is an example that uses a custom Filter implementation. - - - remote-directory="some/remote/path" + + + remote-directory="some/remote/path" - - -]]> + +]]> Poller configuration notes for the inbound FTP adapter @@ -219,25 +218,25 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/ftp 1) Communicate with a remote server in order to transfer files from a remote directory to a local directory. 2) For each transferred file, generate a Message with that file as a payload and send it to the channel identified by the 'channel' attribute. - That is why they are called 'channel-adapters' rather than just 'adapters'. The main job of such an adapter is to generate a - Message to be sent to a Message Channel. Essentially, the second task mentioned above takes precedence in such a way that - *IF* your local directory already has one or more files it will first generate Messages from those, and *ONLY* + That is why they are called 'channel-adapters' rather than just 'adapters'. The main job of such an adapter is to generate a + Message to be sent to a Message Channel. Essentially, the second task mentioned above takes precedence in such a way that + *IF* your local directory already has one or more files it will first generate Messages from those, and *ONLY* when all local files have been processed, will it initiate the remote communication to retrieve more files. - Also, when configuring a trigger on the poller you should pay close attention to the max-messages-per-poll + Also, when configuring a trigger on the poller you should pay close attention to the max-messages-per-poll attribute. Its default value is 1 for all SourcePollingChannelAdapter instances (including FTP). - This means that as soon as one file is processed, it will wait for the next execution time as determined by your - trigger configuration. If you happened to have one or more files sitting in the local-directory, it would process - those files before it would initiate communication with the remote FTP server. And, if the max-messages-per-poll + This means that as soon as one file is processed, it will wait for the next execution time as determined by your + trigger configuration. If you happened to have one or more files sitting in the local-directory, it would process + those files before it would initiate communication with the remote FTP server. And, if the max-messages-per-poll were set to 1 (default), then it would be processing only one file at a time with intervals as defined by your trigger, essentially working as one-poll = one-file. - For typical file-transfer use cases, you most likely want the opposite behavior: to process all the files you can for each + For typical file-transfer use cases, you most likely want the opposite behavior: to process all the files you can for each poll and only then wait for the next poll. If that is the case, set max-messages-per-poll to -1. Then, on - each poll, the adapter will attempt to generate as many Messages as it possibly can. In other words, it will process - everything in the local directory, and then it will connect to the remote directory to transfer everything that is available + each poll, the adapter will attempt to generate as many Messages as it possibly can. In other words, it will process + everything in the local directory, and then it will connect to the remote directory to transfer everything that is available there to be processed locally. Only then is the poll operation considered complete, and the poller will wait for the next execution time. @@ -245,51 +244,51 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/ftp from files with each poll. For example, a value of 10 means that on each poll it will attempt to process no more than 10 files.
- +
FTP Outbound Channel Adapter - + - The FTP Outbound Channel Adapter relies upon a MessageHandler implementation that will connect to the - FTP server and initiate an FTP transfer for every file it receives in the payload of incoming Messages. It also supports several + The FTP Outbound Channel Adapter relies upon a MessageHandler implementation that will connect to the + FTP server and initiate an FTP transfer for every file it receives in the payload of incoming Messages. It also supports several representations of the File so you are not limited only to java.io.File typed payloads. - The FTP Outbound Channel Adapter - supports the following payloads: 1) java.io.File - the actual file object; - 2) byte[] - a byte array that represents the file contents; and 3) java.lang.String - + The FTP Outbound Channel Adapter + supports the following payloads: 1) java.io.File - the actual file object; + 2) byte[] - a byte array that represents the file contents; and 3) java.lang.String - text that represents the file contents. - + ]]> + channel="ftpChannel" + session-factory="ftpSessionFactory" + charset="UTF-8" + remote-file-separator="/" + auto-create-directory="true" + remote-directory-expression="headers.['remote_dir']" + temporary-remote-directory-expression="headers.['temp_remote_dir']" + filename-generator="fileNameGenerator"/>]]> As you can see from the configuration above you can configure an FTP Outbound Channel Adapter via the - outbound-channel-adapter element while also providing values for various attributes such as filename-generator + outbound-channel-adapter element while also providing values for various attributes such as filename-generator (an implementation of the org.springframework.integration.file.FileNameGenerator strategy interface), a reference to a session-factory, as well as other attributes. You can also see - some examples of *expression attributes which allow you to use SpEL - to configure things like remote-directory-expression, temporary-remote-directory-expression and remote-filename-generator-expression - (a SpEL alternative to filename-generator shown above). As with any component that allows the usage of SpEL, access to Payload and Message Headers is available via + some examples of *expression attributes which allow you to use SpEL + to configure things like remote-directory-expression, temporary-remote-directory-expression and remote-filename-generator-expression + (a SpEL alternative to filename-generator shown above). As with any component that allows the usage of SpEL, access to Payload and Message Headers is available via 'payload' and 'headers' variables. Please refer to the schema for more details on the available attributes. - By default Spring Integration will use org.springframework.integration.file.DefaultFileNameGenerator if none is specified. + By default Spring Integration will use o.s.i.file.DefaultFileNameGenerator if none is specified. DefaultFileNameGenerator will determine the file name based on the value of the file_name header (if it exists) in the MessageHeaders, or if the payload of the Message is already a java.io.File, then it will use the original name of that file. - + - Defining certain values (e.g., remote-directory) might be platform/ftp server dependent. For example as it - was reported on this forum http://forum.springsource.org/showthread.php?p=333478&posted=1#post333478 on some - platforms you must add slash to the end of the directory definition (e.g., remote-directory="/foo/bar/" + Defining certain values (e.g., remote-directory) might be platform/ftp server dependent. For example as it + was reported on this forum http://forum.springsource.org/showthread.php?p=333478&posted=1#post333478 on some + platforms you must add slash to the end of the directory definition (e.g., remote-directory="/foo/bar/" instead of remote-directory="/foo/bar") @@ -407,13 +406,12 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/ftp Here is an example of a gateway configured for an ls command... -]]> + session-factory="ftpSessionFactory" + request-channel="inbound1" + command="ls" + command-options="-1" + expression="payload" + reply-channel="toSplitter"/>]]> The payload of the message sent to the toSplitter channel is a list of String objects @@ -433,23 +431,23 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/ftp of the CachingSessionFactory instance. That provides the sessionCacheSize and sessionWaitTimeout properties. As its name suggests, the sessionCacheSize property controls how many active sessions this adapter will maintain in its cache (the DEFAULT is unbounded). If the sessionCacheSize threshold has been reached, any attempt to - acquire another session will block until either one of the cached sessions becomes available or until the wait time for a Session + acquire another session will block until either one of the cached sessions becomes available or until the wait time for a Session expires (the DEFAULT wait time is Integer.MAX_VALUE). The sessionWaitTimeout property enables configuration of that value. If you want your Sessions to be cached, simply configure your default Session Factory as described above and then wrap it in an instance of CachingSessionFactory where you may provide those additional properties. + + + + - - - - - - - - - ]]> - + + + + +]]> + In the above example you see a CachingSessionFactory created with the sessionCacheSize set to 10 and the sessionWaitTimeout set to 1 second (its value is in millliseconds). diff --git a/src/reference/docbook/gateway.xml b/src/reference/docbook/gateway.xml index 32295be5e8..f4ed93d69f 100644 --- a/src/reference/docbook/gateway.xml +++ b/src/reference/docbook/gateway.xml @@ -89,12 +89,12 @@ public interface Cafe { @Gateway annotation. - +}]]> You may alternatively provide such content in method sub-elements if you prefer XML configuration (see the next paragraph). @@ -102,12 +102,12 @@ public interface Cafe { It is also possible to pass values to be interpreted as Message headers on the Message that is created and sent to the request channel by using the @Header annotation: - +}]]> If you prefer the XML approach of configuring Gateway methods, you can provide method sub-elements @@ -391,20 +391,18 @@ int finalResult =  result.get(1000, TimeUnit.SECONDS); behave like that containing a service-activator with the 'requires-reply' attribute. In other words, it will help to ensure a timely response from the Gateway method invocation. - - - - * reply-timeout is unbounded for <gateway/> - elements (created by the GatewayProxyFactoryBean). Inbound gateways for external integration - (ws, http, etc.) share many characteristics and attributes with these gateways. However, - for those inbound gateways, the default reply-timeout is 1000 - milliseconds (1 second). If a downstream async handoff is made to another thread, you may need to - increase this attribute to allow enough time for the flow to complete before the - gateway times out. - - - - + + + + * reply-timeout is unbounded for <gateway/> + elements (created by the GatewayProxyFactoryBean). Inbound gateways for external integration + (ws, http, etc.) share many characteristics and attributes with these gateways. However, + for those inbound gateways, the default reply-timeout is 1000 + milliseconds (1 second). If a downstream async handoff is made to another thread, you may need to + increase this attribute to allow enough time for the flow to complete before the + gateway times out. + +
diff --git a/src/reference/docbook/gemfire.xml b/src/reference/docbook/gemfire.xml index 99c41fc9f3..6bcc648d4a 100644 --- a/src/reference/docbook/gemfire.xml +++ b/src/reference/docbook/gemfire.xml @@ -9,22 +9,22 @@
Introduction - VMWare vFabric GemFire (GemFire) is a distributed data management platform providing a key-value data grid along with advanced distributed system features such as event processing, continuous querying, and + VMWare vFabric GemFire (GemFire) is a distributed data management platform providing a key-value data grid along with advanced distributed system features such as event processing, continuous querying, and remote function execution. This guide assumes some familiarity with GemFire and its API. - Spring integration provides support for GemFire by providing inbound adapters for entry and continuous query events, - an outbound adapter to write entries to the cache, and MessageStore and MessageGroupStore implementations. - Spring integration leverages the + Spring integration provides support for GemFire by providing inbound adapters for entry and continuous query events, + an outbound adapter to write entries to the cache, and MessageStore and MessageGroupStore implementations. + Spring integration leverages the Spring Gemfire project, providing a thin wrapper over its components. To configure the 'int-gfe' namespace, include the following elements within the headers of your XML configuration file: - +
@@ -32,106 +32,97 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/gemfire Inbound Channel Adapter The inbound-channel-adapter produces messages on a channel triggered by a GemFire EntryEvent. GemFire - generates events whenever an entry is CREATED, UPDATED, DESTROYED, or INVALIDATED in the associated region. The inbound channel adapter allows you to filter on a subset of these - events. For example, you may want to only produce messages in response to an entry being CREATED. In addition, the inbound channel adapter can evaluate a SpEL - expression if, for example, you want your message payload to contain an event property such as the new entry value. - - - - - ]]> - + generates events whenever an entry is CREATED, UPDATED, DESTROYED, or INVALIDATED in the associated region. The inbound channel adapter allows you to filter on a subset of these + events. For example, you may want to only produce messages in response to an entry being CREATED. In addition, the inbound channel adapter can evaluate a SpEL + expression if, for example, you want your message payload to contain an event property such as the new entry value. - In the above configuration, we are creating a GemFire Cache and Region using Spring GemFire's 'gfe' namespace. - The inbound-channel-adapter requires a reference to the GemFire region for which the adapter will be listening for events. Optional attributes include cache-events + + +]]> + + In the above configuration, we are creating a GemFire Cache and Region using Spring GemFire's 'gfe' namespace. + The inbound-channel-adapter requires a reference to the GemFire region for which the adapter will be listening for events. Optional attributes include cache-events which can contain a comma separated list of event types for which a message will be produced on the input channel. By default CREATED and UPDATED are enabled. Note that this adapter conforms to Spring integration conventions. If no channel attribute is provided, the channel will be created from the id attribute. This adapter also supports an error-channel. - If expression is not provided the message payload will be a GemFire EntryEvent + If expression is not provided the message payload will be a GemFire EntryEvent
Continuous Query Inbound Channel Adapter The cq-inbound-channel-adapter produces messages a channel triggered by a GemFire continuous query or CqEvent event. Spring GemFire introduced - continuous query support in release 1.1, including a ContinuousQueryListenerContainer which provides a nice abstraction over the GemFire native API. This adapter requires a - reference to a ContinuousQueryListenerContainer, and creates a listener for a given query and executes the query. The continuous query acts as an event source that will fire whenever its - result set changes state. + continuous query support in release 1.1, including a ContinuousQueryListenerContainer which provides a nice abstraction over the GemFire native API. This adapter requires a + reference to a ContinuousQueryListenerContainer, and creates a listener for a given query and executes the query. The continuous query acts as an event source that will fire whenever its + result set changes state. - GemFire queries are written in OQL and are scoped to the entire cache (not just one region). Additionally, continuous queries require a remote (i.e., running in a separate process or remote host) - cache server. Please consult the GemFire documentation for more information on + GemFire queries are written in OQL and are scoped to the entire cache (not just one region). Additionally, continuous queries require a remote (i.e., running in a separate process or remote host) + cache server. Please consult the GemFire documentation for more information on implementing continuous queries. - - - - - - - - - - - - - - - ]]> - + - In the above configuration, we are creating a GemFire client cache + + + + + + + + + + + +]]> + + In the above configuration, we are creating a GemFire client cache (recall a remote cache server is required for this implementation and its address is configured as a sub-element of the pool), a client region and a ContinuousQueryListenerContainer using Spring GemFire. The continuous query inbound channel adapter requires a cq-listener-container attribute which contains a reference to the ContinuousQueryListenerContainer. Optionally, it accepts an expression attribute which uses SpEL to transform the CqEvent or extract an individual property as needed. The cq-inbound-channel-adapter provides a query-events attribute, containing a comma separated list of event types for which a message will be produced on the input channel. Available event types are CREATED, UPDATED, DESTROYED, - REGION_DESTROYED, REGION_INVALIDATED. CREATED and UPDATED are enabled by default. Additional optional attributes include, query-name which provides an optional query name, and + REGION_DESTROYED, REGION_INVALIDATED. CREATED and UPDATED are enabled by default. Additional optional attributes include, query-name which provides an optional query name, and expression which works as described in the above section, and durable - a boolean value indicating if the query is durable (false by default). Note that this adapter conforms to Spring integration conventions. - If no channel attribute is provided, the channel will be created from the id attribute. This adapter also supports an error-channel + If no channel attribute is provided, the channel will be created from the id attribute. This adapter also supports an error-channel
- +
Outbound Channel Adapter - The outbound-channel-adapter writes cache entries mapped from the message payload. In its simplest form, it expects a - payload of type java.util.Map and puts the map entries into its configured region. - -]]> - - - Given the above configuration, an exception will be thrown if the payload is not a Map. Additionally, the outbound channel adapter can be configured to create a - map of cache entries using SpEL of course. - - - + The outbound-channel-adapter writes cache entries mapped from the message payload. In its simplest form, it expects a + payload of type java.util.Map and puts the map entries into its configured region. + +]]> + + Given the above configuration, an exception will be thrown if the payload is not a Map. Additionally, the outbound channel adapter can be configured to create a + map of cache entries using SpEL of course. + + + - - -]]> - - In the above configuration, the inner element cache-entries is semantically equivalent to Spring 'map' element. The adapter interprets the key and - value attributes as SpEL expressions with the message as the evaluation context. Note that this contain - arbitrary cache entries (not only those derived from the message) and that literal values must be enclosed in single quotes. In the above example, if the message sent to - cacheChannel has a String payload with a value "Hello", two entries [HELLO:hello, foo:bar] will be written (created or updated) in the cache region. - This adapter also supports the order attribute which may be useful if it is bound to a PublishSubscribeChannel. + +]]> + In the above configuration, the inner element cache-entries is semantically equivalent to Spring 'map' element. The adapter interprets the key and + value attributes as SpEL expressions with the message as the evaluation context. Note that this contain + arbitrary cache entries (not only those derived from the message) and that literal values must be enclosed in single quotes. In the above example, if the message sent to + cacheChannel has a String payload with a value "Hello", two entries [HELLO:hello, foo:bar] will be written (created or updated) in the cache region. + This adapter also supports the order attribute which may be useful if it is bound to a PublishSubscribeChannel.
- +
Gemfire Message Store - + As described in EIP, a Message Store allows you to persist Messages. This can be very useful when dealing with components that have a capability to buffer messages (QueueChannel, Aggregator, Resequencer, etc.) if reliability is a concern. - In Spring Integration, the MessageStore strategy also provides the foundation for the + In Spring Integration, the MessageStore strategy also provides the foundation for the ClaimCheck pattern, which is described in EIP as well. @@ -140,11 +131,10 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/gemfire the MessageStore strategy (mainly used by the QueueChannel and ClaimCheck patterns) and the MessageGroupStore strategy (mainly used by the Aggregator and Resequencer patterns). - - + + - + @@ -152,32 +142,28 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/gemfire -]]> + message-store="gemfireMessageStore"/>]]> Above is a sample GemfireMessageStore configuration that shows its usage by a QueueChannel and an Aggregator. As you can see it is a normal Spring bean configuration. The simplest configuration requires a reference to a GemFireCache (created by CacheFactoryBean) as a constructor argument. If the cache is standalone, i.e., embedded in the same JVM, the MessageStore will create a message store region named "messageStoreRegion". If your application requires customization of the messageStore region, for example, multiple Gemfire message stores each with its own region, you can configure a region for each message store instance and use the Region as the constructor argument: - - + + - -]]> +]]> In the above examle, the cache and region are configured using the spring-gemfire namespace (not to be confused with the spring-integration-gemfire namespace). Often it is desirable for the message store to be maintained in one or more remote cache servers in a client-server configuration (See the GemFire product documentation for more details). In this case, you configure a client cache, client region, and client pool and inject the region into the MessageStore. Here is an example: - - + + @@ -185,9 +171,8 @@ In the above examle, the cache and region are configured using the spring-gemfir - - -]]> + +]]> Note the pool element is configured with the address of a cache server (a locator may be substituted here). The region is configured as a 'PROXY' so that no data will be stored locally. The region's id corresponds to a region with the same name configured in the cache server. diff --git a/src/reference/docbook/handler-advice.xml b/src/reference/docbook/handler-advice.xml index d2b5af55fb..e612fc67d7 100644 --- a/src/reference/docbook/handler-advice.xml +++ b/src/reference/docbook/handler-advice.xml @@ -30,13 +30,13 @@ Spring Integration 2.2 adds the ability to add behavior to individual endpoints. This is achieved by the addition of the <request-handler-advice-chain /> element to many endpoints. For example: - - - - + + + + ]]> In this case, myRetryAdvice will only be applied locally to this gateway and @@ -76,7 +76,7 @@
Retry Advice - The retry advice (org.springframework.integration.handler.advice.RequestHandlerRetryAdvice) + The retry advice (o.s.i.handler.advice.RequestHandlerRetryAdvice) leverages the rich retry mechanisms provided by the spring-retry project. The core component of spring-retry is the RetryTemplate, which allows configuration @@ -113,11 +113,11 @@ Configuring the Retry Advice The following examples use a simple <service-activator />> that always throws an exception: - Simple Stateless Retry @@ -130,13 +130,12 @@ environment, this final exception might be handled using an error-channel on the inbound endpoint. - - - - + + + + - DEBUG [task-scheduler-2]preSend on channel 'input', message: [Payload=...] DEBUG [task-scheduler-2]Retry: count=0 DEBUG [task-scheduler-2]Checking for rethrow: count=1 @@ -151,19 +150,18 @@ DEBUG [task-scheduler-2]Retry failed last attempt: count=3]]>ErrorMessageSendingRecoverer to send an ErrorMessage to a channel. - - - - - - - - - - + + + + + + + + + + - DEBUG [task-scheduler-2]preSend on channel 'input', message: [Payload=...] DEBUG [task-scheduler-2]Retry: count=0 DEBUG [task-scheduler-2]Checking for rethrow: count=1 @@ -181,17 +179,17 @@ DEBUG [task-scheduler-2]Sending ErrorMessage :failedMessage:[Payload=...]]]> - - - - - - - - - - - + + + + + + + + + + + @@ -208,7 +206,6 @@ DEBUG [task-scheduler-2]Sending ErrorMessage :failedMessage:[Payload=...]]]> - 27.058 DEBUG [task-scheduler-1]preSend on channel 'input', message: [Payload=...] 27.071 DEBUG [task-scheduler-1]Retry: count=0 27.080 DEBUG [task-scheduler-1]Sleeping for 1000 @@ -233,25 +230,23 @@ DEBUG [task-scheduler-2]Sending ErrorMessage :failedMessage:[Payload=...]]]> - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - 24.351 DEBUG [Container#0-1]preSend on channel 'input', message: [Payload=...] 24.368 DEBUG [Container#0-1]Retry: count=0 24.387 DEBUG [Container#0-1]Checking for rethrow: count=1 @@ -299,7 +294,7 @@ Caused by: java.lang.RuntimeException: foo The general idea of the Circuit Breaker Pattern is that, if a service is not currently available, then don't waste time (and resources) trying to use it. The - org.springframework.integration.handler.advice.RequestHandlerCircuitBreakerAdvice + o.s.i.handler.advice.RequestHandlerCircuitBreakerAdvice implements this pattern. When the circuit breaker is in the closed state, the endpoint will attempt to invoke the service. The circuit breaker goes to the open state @@ -327,16 +322,15 @@ Caused by: java.lang.RuntimeException: foo 1000 milliseconds. Example: - - - - - - - + + + + + + + - 05.617 DEBUG [task-scheduler-1]preSend on channel 'input', message: [Payload=...] 05.638 ERROR [task-scheduler-1]org.springframework.integration.MessageHandlingException: java.lang.RuntimeException: foo ... @@ -366,7 +360,7 @@ Caused by: java.lang.RuntimeException: foo Expression Evaluating Advice The final supplied advice class is the - org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice. + o.s.i.handler.advice.ExpressionEvaluatingRequestHandlerAdvice. This advice is more general than the other two advices. It provides a mechanism to evaluate an expression on the original inbound message sent to the endpoint. Separate expressions are available to be evaluated, either after success, or failure. Optionally, a message containing the evaluation result, together with the input message, @@ -395,23 +389,23 @@ Caused by: java.lang.RuntimeException: foo In addition to the provided Advice classes above, you can implement your own Adivce classes. While you can provide any implementation of org.aopalliance.aop.Advice, it is generally recommended - that you subclass org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice. + that you subclass o.s.i.handler.advice.AbstractRequestHandlerAdvice. This has the benefit of avoiding writing low-level Aspect Oriented Programming code as well as providing a starting point that is specifically tailored for use in this environment. Subclasses need to implement the doInvoke() method: - message) throws Exception;]]> + message) throws Exception;]]> The callback parameter is simply a convenience to avoid subclasses dealing with AOP directly; invoking the @@ -438,15 +432,15 @@ Caused by: java.lang.RuntimeException: foo ability to modify the return value. Note that only AbstractReplyProducingMessageHandlers return a value. - message) throws Exception { - // add code before the invocation - Object result = callback.execute(); - // add code after the invocation - return result; - } + @Override + protected Object doInvoke(ExecutionCallback callback, Object target, Message message) throws Exception { + // add code before the invocation + Object result = callback.execute(); + // add code after the invocation + return result; + } }]]> diff --git a/src/reference/docbook/http.xml b/src/reference/docbook/http.xml index 2c5633a36f..76ac32de22 100644 --- a/src/reference/docbook/http.xml +++ b/src/reference/docbook/http.xml @@ -200,7 +200,7 @@ In the case of the Outbound Gateway, the reply message produced by the gateway w inbound-gateway: - ]]> @@ -267,10 +267,10 @@ In the case of the Outbound Gateway, the reply message produced by the gateway w - + path="/first-name/{firstName}/last-name/{lastName}" + channel="requests" + payload-expression="#pathVariables.firstName"> + ]]> @@ -349,15 +349,15 @@ In the case of the Outbound Gateway, the reply message produced by the gateway w a successful response will simply execute without sending any Messages to a reply channel. In the case of any non-successful response status code, it will throw an exception. The configuration looks very similar to the gateway: ]]> + url="http://localhost/example" + http-method="GET" + channel="requests" + charset="UTF-8" + extract-payload="false" + expected-response-type="java.lang.String" + request-factory="someRequestFactory" + order="3" + auto-startup="false"/>]]> @@ -386,10 +386,10 @@ In the case of the Outbound Gateway, the reply message produced by the gateway w - + request-channel="trafficChannel" + http-method="GET" + expected-response-type="java.lang.String"> + ]]> The uri-variable sub-element defines two attributes: @@ -632,20 +632,20 @@ In the case of the Outbound Gateway, the reply message produced by the gateway w If for any reason, you need more explicit control over the proxy configuration, you can use Spring's SimpleClientHttpRequestFactory and configure its 'proxy' property as such: - - - - - - - - - - - - - + class="org.springframework.http.client.SimpleClientHttpRequestFactory"> + + + + + + + + + + + + + ]]> @@ -668,15 +668,15 @@ In the case of the Outbound Gateway, the reply message produced by the gateway w HTTP_RESPONSE_HEADERS. Here are some examples: + url="http://localhost/test2" + mapped-request-headers="foo, bar" + mapped-response-headers="X-*, HTTP_RESPONSE_HEADERS" + channel="someChannel"/> ]]> + url="http://localhost/test2" + mapped-request-headers="foo, bar, HTTP_REQUEST_HEADERS" + channel="someChannel"/>]]> The adapters and gateways will use the DefaultHttpHeaderMapper which now provides two static factory methods for "inbound" and "outbound" adapters so that the proper direction can be @@ -687,13 +687,13 @@ In the case of the Outbound Gateway, the reply message produced by the gateway w and inject it into the adapter via the header-mapper attribute. + url="http://localhost/test2" + header-mapper="headerMapper" + channel="someChannel"/> - - - + + + ]]> Of course, you can even implement the HeaderMapper strategy interface directly and provide a reference to that @@ -728,36 +728,35 @@ That is all for the client. On the server side we have the following configuration: + channel="receiveChannel" + name="/inboundAdapter.htm" + supported-methods="GET, POST"/> - + -]]> + class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>]]> The 'httpInboundAdapter' will receive the request, convert it to a Message with a payload that is a LinkedMultiValueMap. We then are parsing that in the 'multipartReceiver' service-activator; multipartRequest){ - System.out.println("### Successfully received multipart request ###"); - for (String elementName : multipartRequest.keySet()) { - if (elementName.equals("company")){ - System.out.println("\t" + elementName + " - " + - ((String[]) multipartRequest.getFirst("company"))[0]); + System.out.println("### Successfully received multipart request ###"); + for (String elementName : multipartRequest.keySet()) { + if (elementName.equals("company")){ + System.out.println("\t" + elementName + " - " + + ((String[]) multipartRequest.getFirst("company"))[0]); + } + else if (elementName.equals("company-logo")){ + System.out.println("\t" + elementName + " - as UploadedMultipartFile: " + + ((UploadedMultipartFile) multipartRequest + .getFirst("company-logo")).getOriginalFilename()); + } } - else if (elementName.equals("company-logo")){ - System.out.println("\t" + elementName + " - as UploadedMultipartFile: " + - ((UploadedMultipartFile) multipartRequest.getFirst("company-logo")). - getOriginalFilename()); - } - } } ]]> diff --git a/src/reference/docbook/ip.xml b/src/reference/docbook/ip.xml index 1c37cbee54..03d49fabf2 100644 --- a/src/reference/docbook/ip.xml +++ b/src/reference/docbook/ip.xml @@ -37,18 +37,18 @@ or I/O error occurs. - The TCP and UDP inbound channel adapters, and the TCP inbound gateway, support the "error-channel" attribute. + The TCP and UDP inbound channel adapters, and the TCP inbound gateway, support the "error-channel" attribute. This provides the same basic functionality as described in .
UDP Adapters - ]]> + channel="exampleChannel"/>]]> A simple UDP outbound channel adapter. When setting multicast to true, provide the multicast address in the host @@ -62,12 +62,12 @@ short the contain the packet, the packet can be truncated. The length header provides a mechanism to detect this. - ]]> + channel="exampleChannel"/>]]> An outbound channel adapter that adds length checking to the datagram packets. The recipient of the packet must also be configured to expect a length to precede the @@ -80,7 +80,7 @@ must send an acknowledgment to the sender within a specified time. - ]]> + channel="exampleChannel"/>]]> An outbound channel adapter that adds length checking to the datagram packets and waits for an acknowledgment. Setting acknowledge to true implies the recipient of the packet can interpret the header added to the packet @@ -105,26 +105,26 @@ For even more reliable networking, TCP can be used. - ]]> + check-length="true"/>]]> A basic unicast inbound udp channel adapter. - ]]> + check-length="true"/>]]> A basic multicast inbound udp channel adapter. - By default, reverse DNS lookups are done on inbound packets to convert IP addresses to + By default, reverse DNS lookups are done on inbound packets to convert IP addresses to hostnames for use in message headers. In environments where DNS is not configured, this can cause delays. This default behavior can be overridden by setting the lookup-host @@ -175,46 +175,38 @@ java.nio.channel.SocketChannel are provided. - ]]> + port="1234"/>]]> A simple server connection factory that uses java.net.Socket connections. - ]]> + using-nio="true"/>]]> A simple server connection factory that uses java.nio.channel.SocketChannel connections. - ]]> + so-timeout="10000"/>]]> A client connection factory that uses java.net.Socket connections and creates a new connection for each message. - ]]> + using-nio=true/>]]> A client connection factory that uses java.nio.channel.Socket connections and creates a new connection for each message. @@ -226,24 +218,24 @@ deserializer and serializer for inbound and outbound messages respectively. A number of standard (de)serializers are provided. - + The ByteArrayCrlfSerializer, converts a byte array to a stream of bytes followed by carriage return and linefeed characters (\r\n). This is the default (de)serializer and can be used with - telnet as a client, for example. + telnet as a client, for example. - + The ByteArrayStxEtxSerializer, converts a byte array to a stream of bytes preceded by an STX (0x02) and - followed by an ETX (0x03). + followed by an ETX (0x03). - + The ByteArrayLengthHeaderSerializer, converts a byte array to a stream of bytes preceded by a binary - length in network byte order (big endian). This a very efficient deserializer + length in network byte order (big endian). This a very efficient deserializer because it does not have to parse every byte looking for a termination character sequence. It can also be used for payloads containing binary data; - the above serializers only support text in the payload. The default size of + the above serializers only support text in the payload. The default size of the length header is 4 bytes (Integer), allowing for messages up to 2**31-1 bytes. However, the length header can be a single byte (unsigned) for messages up to 255 bytes, or an unsigned short (2 bytes) for messages up to @@ -251,12 +243,12 @@ this class and provide implementations for the readHeader and writeHeader methods. The absolute maximum data size supported is 2**31-1 bytes. - + The ByteArrayRawSerializer, converts a byte array to a stream of bytes and adds no additional message demarcation data; with this (de)serializer, the end of a message is indicated - by the client closing the socket in an orderly fashion. When using this serializer, - message reception will hang until the client closes the socket, or a timeout occurs; + by the client closing the socket in an orderly fashion. When using this serializer, + message reception will hang until the client closes the socket, or a timeout occurs; a timeout will NOT result in a message. When this serializer is being used, and the client is a Spring Integration application, the client must use a connection factory that is configured with single-use=true - this causes the adapter to close the socket after sending @@ -273,7 +265,7 @@ AbstractByteArraySerializer for serialization will also accept a String which will be converted to a byte array first. Each of these (de)serializers converts an input stream containing the - corresponding format to a byte array payload. + corresponding format to a byte array payload. To avoid memory exhaustion due to a badly behaved client (one that does not adhere to @@ -294,27 +286,25 @@ To implement a custom (de)serializer pair, implement the org.springframework.core.serializer.Deserializer and - org.springframework.core.serializer.Serializer interfaces. + org.springframework.core.serializer.Serializer interfaces. - + If you do not wish to use the default (de)serializer (ByteArrayCrLfSerializer), you must supply serializer and deserializer attributes on the connection factory (example below). - - + + - ]]> + serializer="javaSerializer"/>]]> A server connection factory that uses java.net.Socket connections and uses Java serialization on the wire. @@ -323,7 +313,7 @@ reference at the end of this section. - By default, reverse DNS lookups are done on inbound packets to convert IP addresses to + By default, reverse DNS lookups are done on inbound packets to convert IP addresses to hostnames for use in message headers. In environments where DNS is not configured, this can cause connection delays. This default behavior can be overridden by setting the lookup-host @@ -365,7 +355,7 @@ factories until either the message can be sent, or no connection can be found. Initially, the first factory in the configured list is used; if a connection subsequently fails the next - factory will become the current factory. + factory will become the current factory. @@ -375,15 +365,14 @@ - - ]]> +]]> When using the failover connection factory, the singleUse property must be consistent between the factory itself and the list of factories it is configured to use. -
+
TCP Connection Interceptors @@ -426,31 +415,29 @@ - - - - - + class="o.s.i.ip.tcp.connection.TcpConnectionInterceptorFactoryChain"> + + + + + + type="server" + port="12345" + using-nio="true" + single-use="true" + interceptor-factory-chain="helloWorldInterceptorFactory"/> ]]> + type="client" + host="localhost" + port="12345" + single-use="true" + so-timeout="100000" + using-nio="true" + interceptor-factory-chain="helloWorldInterceptorFactory"/>]]> Configuring a connection interceptor factory chain.
@@ -498,54 +485,51 @@ to a connection factory.
- - + + - + single-use="true"/> - + serializer="javaSerializer"/> - + - + - + - - - - - ]]> +]]> In this configuration, messages arriving in channel 'input' are serialized over connections created by 'client' received at the server and placed on channel 'loop'. Since 'loop' is @@ -571,7 +555,7 @@ Two additional attributes are used to support this mechanism: retry-interval specifies (in milliseconds) - how often the framework will attempt to reconnect after a + how often the framework will attempt to reconnect after a connection failure. scheduler is used to supply a TaskScheduler used to schedule the connection attempts, and to test that the connection is @@ -584,7 +568,7 @@ when the adapter is started. Adapters are automatically started by default. Again, the connection factory must be of type client and have single-use set to false and - retry-interval and + retry-interval and scheduler are also supported. If a connection fails, it will be re-established either by the scheduler or when the next message is sent. @@ -616,19 +600,19 @@ For the inbound gateway, care must be taken to retain, or populate, the ip_connnection_id header because it is used to correlate the message to a connection. Messages that originate at the - gateway will automatically have the header set. If the reply is + gateway will automatically have the header set. If the reply is constructed as a new message, you will need to set the header. The header value can be captured from the incoming message. - As with inbound adapters, inbound gateways normally use a + As with inbound adapters, inbound gateways normally use a type="server" connection factory, which listens for incoming connection requests. In some cases, it is desireable to establish the connection in reverse, whereby the inbound gateway connects to an - external server and then waits for, and replies to, inbound + external server and then waits for, and replies to, inbound messages on that connection. @@ -640,7 +624,7 @@ Two additional attributes are used to support this mechanism: retry-interval specifies (in milliseconds) - how often the framework will attempt to reconnect after a + how often the framework will attempt to reconnect after a connection failure. scheduler is used to supply a TaskScheduler used to schedule the connection attempts, and to test that the connection is @@ -664,25 +648,23 @@ ]]> + reply-timeout="10000"/>]]>
A simple inbound TCP gateway; if a connection factory configured with the default (de)serializer is used, messages will be \r\n delimited data and the gateway can be used by a simple client such as telnet. ]]> + remote-timeout="10000"/>]]> A simple outbound TCP gateway. @@ -692,11 +674,11 @@ Overview One goal of the IP Endpoints is to provide communication with systems other - than another Spring Integration application. For this reason, only + than another Spring Integration application. For this reason, only message payloads are sent and received. No message correlation is provided by the framework, - except when using the gateways, or collaborating channel adapters on the - server side. In the paragraphs below we discuss the various + except when using the gateways, or collaborating channel adapters on the + server side. In the paragraphs below we discuss the various correlation techniques available to applications. In most cases, this requires specific application-level correlation of messages, even when message payloads contain some natural correlation data (such as an order @@ -707,17 +689,17 @@ Gateways The gateways will automatically correlate messages. However, an outbound - gateway should only be used for relatively low-volume use. + gateway should only be used for relatively low-volume use. When the connection factory is configured for a single shared connection - to be used for all message pairs ('single-use="false"'), + to be used for all message pairs ('single-use="false"'), only one message can be processed at a time. A new message will have to wait until the reply to the previous message has - been received. - When a connection factory is configured for each new message to use a new connection + been received. + When a connection factory is configured for each new message to use a new connection ('single-use="true"'), the above restriction does not apply. While this may give higher throughput than a shared connection environment, it comes with the overhead of opening - and closing a new connection for each message pair. + and closing a new connection for each message pair. Therefore, for high-volume messages, consider using a collaborating pair of @@ -760,39 +742,39 @@ This can be done in a number of ways. - If the message payload has some natural correlation data, such as a + If the message payload has some natural correlation data, such as a transaction id or an order number, AND there is no need to retain any information (such as a reply channel header) from the original outbound message, - the correlation is simple and would done at the application level in any case. + the correlation is simple and would done at the application level in any case. - If the message payload has some natural correlation data, such as a + If the message payload has some natural correlation data, such as a transaction id or an order number, but there is a need to retain some - information (such as a reply channel header) from the original outbound message, + information (such as a reply channel header) from the original outbound message, you may need to retain a copy of the original outbound message (perhaps by using a publish-subscribe channel) and use an aggregator to recombine the necessary data. - For either of the previous two paragraphs, if the payload has no natural + For either of the previous two paragraphs, if the payload has no natural correlation data, you may need to provide a transformer upstream of the - outbound channel adapter to enhance the payload with such data. Such a + outbound channel adapter to enhance the payload with such data. Such a transformer may transform the original payload to a new object containing both the original payload and some subset of the message headers. Of course, - live objects (such as reply channels) from the headers can not be + live objects (such as reply channels) from the headers can not be included in the transformed payload. If such a strategy is chosen you will need to ensure the connection factory has an appropriate serializer/deserializer pair to handle such a payload, - such as the DefaultSerializer/Deserializer which use java - serialization, or a custom serializer and deserializer. + such as the DefaultSerializer/Deserializer which use java + serialization, or a custom serializer and deserializer. The ByteArray*Serializer options mentioned in , - including the default ByteArrayCrLfSerializer, + including the default ByteArrayCrLfSerializer, do not support such payloads, - unless the transformed payload is a String or - byte[], + unless the transformed payload is a String or + byte[], @@ -819,11 +801,11 @@
A Note About NIO - Using NIO (see using-nio in + Using NIO (see using-nio in ) avoids dedicating a thread to read from each socket. For a small number - of sockets, you will likely find that not using NIO, - together with an async handoff (e.g. to a QueueChannel), + of sockets, you will likely find that not using NIO, + together with an async handoff (e.g. to a QueueChannel), will perform as well as, or better than, using NIO. @@ -835,7 +817,7 @@ messages arriving on the same socket might be processed by different threads. This means that the order in which the messages are sent to the channel is indeterminate; the strict ordering of the messages arriving on the - socket is not maintained. + socket is not maintained. For some applications, this is not an issue; for others it is. If strict ordering @@ -926,19 +908,19 @@ TcpSSLContextSupport bean, and provide a reference to that bean to the connection factory. - - - - - - + + + + + + - + The DefaulTcpSSLContextSupport class also has an optional @@ -1124,7 +1106,7 @@ Y Defaults to 0 (infinity), except for - server connection factories with single-use="true". + server connection factories with single-use="true". In that case, it defaults to the default reply timeout (10 seconds). @@ -1348,8 +1330,8 @@ error-channel - If an Exception is thrown by a downstream - component, the MessagingException message containing the exception + If an Exception is thrown by a downstream + component, the MessagingException message containing the exception and failed message is sent to this channel. @@ -1503,17 +1485,17 @@ connection-factory - If the connection factory has a type 'server', the factory is 'owned' - by this adapter. If it has a type 'client', it is 'owned' by an - outbound channel adapter and this adapter will receive any - incoming messages on the connection created by the + If the connection factory has a type 'server', the factory is 'owned' + by this adapter. If it has a type 'client', it is 'owned' by an + outbound channel adapter and this adapter will receive any + incoming messages on the connection created by the outbound adapter. error-channel - If an Exception is thrown by a downstream - component, the MessagingException message containing the exception + If an Exception is thrown by a downstream + component, the MessagingException message containing the exception and failed message is sent to this channel. @@ -1540,7 +1522,7 @@ scheduler true, false - Specifies a TaskScheduler to use for managing the + Specifies a TaskScheduler to use for managing the client-mode connection. Defaults to a ThreadPoolTaskScheduler with a pool size of `. @@ -1571,10 +1553,10 @@ connection-factory - If the connection factory has a type 'client', the factory is - 'owned' by this adapter. If it has a type 'server', it is 'owned' - by an inbound channel adapter and this adapter will attempt - to correlate messages to the connection on which an + If the connection factory has a type 'client', the factory is + 'owned' by this adapter. If it has a type 'server', it is 'owned' + by an inbound channel adapter and this adapter will attempt + to correlate messages to the connection on which an original inbound message was received. @@ -1602,7 +1584,7 @@ scheduler true, false - Specifies a TaskScheduler to use for managing the + Specifies a TaskScheduler to use for managing the client-mode connection. Defaults to a ThreadPoolTaskScheduler with a pool size of `. @@ -1651,8 +1633,8 @@ error-channel - If an Exception is thrown by a downstream - component, the MessagingException message containing the exception + If an Exception is thrown by a downstream + component, the MessagingException message containing the exception and failed message is sent to this channel; any reply from that flow will then be returned as a response by the gateway. @@ -1662,7 +1644,7 @@ true, false When true, the inbound gateway will act as a client, with respect to establishing - the connection and then receive (and reply to) incoming messages on that connection. + the connection and then receive (and reply to) incoming messages on that connection. Default = false. Also see retry-interval and scheduler. The connection factory must be of type 'client' and have single-use @@ -1682,7 +1664,7 @@ scheduler true, false - Specifies a TaskScheduler to use for managing the + Specifies a TaskScheduler to use for managing the client-mode connection. Defaults to a ThreadPoolTaskScheduler with a pool size of `. @@ -1732,7 +1714,7 @@ request-timeout - If a single-use connection factory is not being used, The time in milliseconds + If a single-use connection factory is not being used, The time in milliseconds for which the gateway will wait to get access to the shared connection. diff --git a/src/reference/docbook/jdbc.xml b/src/reference/docbook/jdbc.xml index c01c492db5..424df5048b 100644 --- a/src/reference/docbook/jdbc.xml +++ b/src/reference/docbook/jdbc.xml @@ -782,9 +782,9 @@ ]]> + direction="IN" ]]> ]]> @@ -873,9 +873,9 @@ database. In that case the following configuration for a Stored Procedure Oubound Adapter will be sufficient: - ]]> + ]]> For more sophisticated options consider passing in one or more ProcedureParameter. @@ -1150,9 +1150,9 @@ EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStored request-channel="findAllProcedureRequestChannel" expect-single-result="true" stored-procedure-name="FIND_ALL_COFFEE_BEVERAGES"> - - ]]> + +]]> In the second example, we call a Stored Procedure named @@ -1165,7 +1165,7 @@ EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStored ... }]]> - diff --git a/src/reference/docbook/jms.xml b/src/reference/docbook/jms.xml index 0ec2e68898..9e482ffe38 100644 --- a/src/reference/docbook/jms.xml +++ b/src/reference/docbook/jms.xml @@ -45,9 +45,9 @@ instance or both ConnectionFactory and Destination (a 'destinationName' can be provided in place of the 'destination' reference). The following example defines an inbound Channel Adapter with a Destination reference. - - - ]]> + + +]]> Notice from the configuration that the inbound-channel-adapter is a Polling Consumer. That means that it invokes receive() when triggered. This should only be used in situations where polling is done relatively @@ -68,12 +68,12 @@ String-based payload, a JMS BytesMessage will produce a byte array payload, and a JMS ObjectMessage's Serializable instance will become the Spring Integration Message's payload. If instead you prefer to have the raw JMS Message as the Spring Integration Message's payload, then set 'extract-payload' to false. - - - ]]> + + +]]>
@@ -85,7 +85,7 @@ ConnectionFactory and Destination (a 'destinationName' can be provided in place of the 'destination' reference). The following example defines a message-driven Channel Adapter with a Destination reference. - ]]> + ]]> The Message-Driven adapter also accepts several properties that pertain to the MessageListener container. These values are only considered if you do not provide an actual 'container' reference. In that case, @@ -104,10 +104,9 @@
Finally, the <message-driven-channel-adapter> also accepts the 'error-channel' attribute. This provides the same basic functionality as described in . - -]]> +]]> When comparing this to the generic gateway configuration, or the JMS 'inbound-gateway' that will be discussed below, the key difference here is that we are in a one-way flow since this is a 'channel-adapter', not a gateway. Therefore, the flow downstream from the @@ -154,9 +153,9 @@ ConnectionFactory, and a request Destination (or 'requestDestinationName'). The following example defines a JMS "inbound-gateway" that receives from the JMS queue referenced by the bean id "inQueue" and sends to the Spring Integration channel named "exampleChannel". - ]]> + ]]> Since the gateways provide request/reply behavior instead of unidirectional send or @@ -220,10 +219,10 @@
- ]]> + ]]> The 'outbound-gateway' payload extraction properties are inversely related to those of the 'inbound-gateway' (see the discussion above). That means that the 'extract-request-payload' property value @@ -267,10 +266,10 @@ caution above; therefore cached consumers should not be used in this case. - + ]]> @@ -284,8 +283,7 @@
Attribute Reference - ]]>]]> - ]]> +]]> @@ -529,20 +526,19 @@ Also, to provide some consistency with Marshaller and Unmarshaller interfaces Spring provides MarshallingMessageConverter which you can configure with your own custom Marshallers and Unmarshallers - + - - - - - - - - - ]]> + + + + + + + +]]> @@ -574,7 +570,7 @@ required even though conceptually the goal is to have a single Message Channel. A better option is supported as of Spring Integration version 2.0. Now it is possible to define a single "channel" when using the JMS namespace. - ]]> + ]]> The channel in the above example will behave much like a normal <channel/> element from the main @@ -598,13 +594,13 @@ Since the example above is referencing a JMS Queue instance, it will act as a point-to-point channel. If on the other hand, publish/subscribe behavior is needed, then a separate element can be used, and a JMS Topic can be referenced instead. - ]]> + ]]> For either type of JMS-backed channel, the name of the destination may be provided instead of a reference. - + - ]]> +]]> In the examples above, the Destination names would be resolved by Spring's default @@ -613,9 +609,9 @@ ConnectionFactory is a required property of the channel, but by default the expected bean name would be "connectionFactory". The example below provides both a custom instance for resolution of the JMS Destination names and a different name for the ConnectionFactory. - ]]> + ]]>
diff --git a/src/reference/docbook/jmx.xml b/src/reference/docbook/jmx.xml index 9726bf6b43..00230f8b1a 100644 --- a/src/reference/docbook/jmx.xml +++ b/src/reference/docbook/jmx.xml @@ -61,13 +61,13 @@ ObjectName pattern (e.g. "org.foo:type=Bar,name=*") and the adapter will receive notifications from all MBeans with ObjectNames that match the pattern. In addition, the object-name attribute can contain a SpEL reference to a <util:list/> of ObjectName patterns: - + - org.foo:type=Foo,name=* - org.foo:type=Bar,name=* + org.foo:type=Foo,name=* + org.foo:type=Bar,name=* ]]> The names of the located MBean(s) will be logged when DEBUG level logging is enabled. diff --git a/src/reference/docbook/jpa.xml b/src/reference/docbook/jpa.xml index f193e8d1cc..918f03e8a2 100644 --- a/src/reference/docbook/jpa.xml +++ b/src/reference/docbook/jpa.xml @@ -169,30 +169,30 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - - + + + - - + class="org.springframework.integration.endpoint.EventDrivenConsumer"> + + ]]> For more examples of constructing JPA components purely through Java, @@ -348,19 +348,18 @@ adapters.The xml snippet below shows a sample where a transaction manager is configured with the poller used with an Inbound Channel Adapter. - - - - - - ]]> + + + + +]]> However, it may be necessary to specifically start a transaction when using an Outbound Channel Adapter/Gateway. If a DirectChannel is an input channel for the outbound adapter/gateway, @@ -369,15 +368,16 @@ in a new transaction as below. - - ]]> + request-channel="namedQueryRequestChannel" + reply-channel="namedQueryResponseChannel" + named-query="updateStudentByRollNumber" + entity-manager="em" + gateway-type="UPDATING"> + + ]]> - ]]> + ]]> ]]> @@ -594,9 +594,9 @@ Adapter to persist an entity to the database. ]]> + entity-class="org.springframework.integration.jpa.test.entity.Student" ]]>]]> @@ -815,10 +815,10 @@ public class Student { order="" ]]> + use-payload-as-parameter-source="true" ]]> - ]]> - ]]> + ]]> ]]>]]> @@ -1053,29 +1053,28 @@ public class Student {
Updating Outbound Gateway + auto-startup="true" + entity-class="" + entity-manager="" + entity-manager-factory="" + id="" + jpa-operations="" + jpa-query="" + named-query="" + native-query="" + order="" + parameter-source-factory="" + persist-mode="MERGE" + reply-channel="" ]]> - - + + - - - - ]]> + + +]]> @@ -1102,31 +1101,30 @@ public class Student {
Retrieving Outbound Gateway - - + auto-startup="true" + delete-after-poll="false" + delete-in-batch="false" + entity-class="" + entity-manager="" + entity-manager-factory="" + expect-single-result="false" ]]> + + - - - - ]]> + + +]]> @@ -1188,9 +1186,9 @@ public class Student { as JPA defining parameter. ]]> + reply-channel="entityResponseChannel" ]]>]]> @@ -1219,12 +1217,12 @@ public class Student { Updating Outbound Gateway. - - - ]]> + reply-channel="jpaqlResponseChannel" + jpa-query="update Student s set s.lastName = :lastName where s.rollNumber = :rollNumber" ]]> + + +]]> @@ -1250,12 +1248,12 @@ public class Student { - - - ]]> + reply-channel="retrievingGatewayReplyChannel" + jpa-query="select s from Student s where s.firstName = :firstName and s.lastName = :lastName" + entity-manager="em"> + + +]]> Update using a Named Query @@ -1264,12 +1262,12 @@ public class Student { attribute is used instead, as seen in the xml snippet below. - - - ]]> + reply-channel="namedQueryResponseChannel" + named-query="updateStudentByRollNumber" + entity-manager="em"> + + +]]> You can find a complete Sample application for using Spring diff --git a/src/reference/docbook/mail.xml b/src/reference/docbook/mail.xml index fe2d17670c..c7b1a0adec 100644 --- a/src/reference/docbook/mail.xml +++ b/src/reference/docbook/mail.xml @@ -51,8 +51,7 @@ Integration's own MailReceiver interface, and there are two implementations: Pop3MailReceiver and ImapMailReceiver. The easiest way to instantiate either of these is by passing the 'uri' for a Mail store to the receiver's constructor. For example: - + Another option for receiving mail is the IMAP "idle" command (if supported by the mail server you are using). @@ -69,20 +68,20 @@ Spring Integration provides a namespace for mail-related configuration. To use it, configure the following schema locations. ]]> + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:int-mail="http://www.springframework.org/schema/integration/mail" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/integration/mail + http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd">]]> To configure an outbound Channel Adapter, provide the channel to receive from, and the MailSender: ]]> + mail-sender="mailSender"/>]]> Alternatively, provide the host, username, and password: ]]> + host="somehost" username="someuser" password="somepassword"/>]]> Keep in mind, as with any outbound Channel Adapter, if the referenced channel is a PollableChannel, a <poller> sub-element should be provided with either an interval-trigger or cron-trigger. @@ -124,14 +123,14 @@ false ]]> - + - By default, the ImapMailReceiver will search for Messages based on the default SearchTerm - which is All mails that are RECENT (if supported), that are NOT ANSWERED, that are NOT DELETED, that are NOT SEEN and have not - been processed by this mail receiver (enabled by the use of the custom USER flag or simply NOT FLAGGED if not supported). - Since version 2.2, the SearchTerm used by the ImapMailReceiver is fully configurable + By default, the ImapMailReceiver will search for Messages based on the default SearchTerm + which is All mails that are RECENT (if supported), that are NOT ANSWERED, that are NOT DELETED, that are NOT SEEN and have not + been processed by this mail receiver (enabled by the use of the custom USER flag or simply NOT FLAGGED if not supported). + Since version 2.2, the SearchTerm used by the ImapMailReceiver is fully configurable via the SearchTermStrategy which you can inject via the search-term-strategy attribute. - SearchTermStrategy is a simple strategy interface with a single method that allows you to create an + SearchTermStrategy is a simple strategy interface with a single method that allows you to create an instance of the SearchTerm that will be used by the ImapMailReceiver. - -]]> + +]]> -In the above example instead of relying on the default SearchTermStrategy the +In the above example instead of relying on the default SearchTermStrategy the TestSearchTermStrategy will be used instead - + IMAP IDLE and lost connection - + - When using IMAP IDLE channel adapter there might be situations where connection to the server may be lost - (e.g., network failure) and since Java Mail documentation explicitly states that the actual IMAP API is EXPERIMENTAL it is + When using IMAP IDLE channel adapter there might be situations where connection to the server may be lost + (e.g., network failure) and since Java Mail documentation explicitly states that the actual IMAP API is EXPERIMENTAL it is important to understand the differences in the API and how to deal with them when configuring IMAP IDLE adapters. - Currently Spring Integration Mail adapters was tested with Java Mail 1.4.1 and Java Mail 1.4.3 and depending on which one + Currently Spring Integration Mail adapters was tested with Java Mail 1.4.1 and Java Mail 1.4.3 and depending on which one is used special attention must be payed to some of the java mail properties that needs to be set with regard to auto-reconnect. - The following behavior was observed with GMAIL but should provide you with some tips on how to solve re-connect + The following behavior was observed with GMAIL but should provide you with some tips on how to solve re-connect issue with other providers, however feedback is always welcome. Again, below notes are based on GMAIL. - With Java Mail 1.4.1 if mail.imaps.timeout property is set for a relatively short period of time (e.g., ~ 5 min) - then IMAPFolder.idle() will throw FolderClosedException after this timeout. - However if this property is not set (should be indefinite) the behavior that was observed is that IMAPFolder.idle() - method never returns nor it throws an exception. It will however reconnect automatically if connection was lost for a short - period of time (e.g., under 10 min), but if connection was lost for a long period of time (e.g., over 10 min), then - IMAPFolder.idle() will not throw FolderClosedException nor it will re-establish connection - and will remain in the blocked state indefinitely, thus leaving you no possibility to reconnect without restarting the adapter. - So the only way to make re-connect to work with Java Mail 1.4.1 is to set mail.imaps.timeout property explicitly - to some value, but it also means that such value shoudl be relatively short (under 10 min) and the connection should be + With Java Mail 1.4.1 if mail.imaps.timeout property is set for a relatively short period of time (e.g., ~ 5 min) + then IMAPFolder.idle() will throw FolderClosedException after this timeout. + However if this property is not set (should be indefinite) the behavior that was observed is that IMAPFolder.idle() + method never returns nor it throws an exception. It will however reconnect automatically if connection was lost for a short + period of time (e.g., under 10 min), but if connection was lost for a long period of time (e.g., over 10 min), then + IMAPFolder.idle() will not throw FolderClosedException nor it will re-establish connection + and will remain in the blocked state indefinitely, thus leaving you no possibility to reconnect without restarting the adapter. + So the only way to make re-connect to work with Java Mail 1.4.1 is to set mail.imaps.timeout property explicitly + to some value, but it also means that such value shoudl be relatively short (under 10 min) and the connection should be re-estabished relatively quickly. Again, it may be different with other providers. - With Java Mail 1.4.3 there was significant improvements to the API ensuring that there will always be a condition which - will force IMAPFolder.idle() method to return via StoreClosedException or + With Java Mail 1.4.3 there was significant improvements to the API ensuring that there will always be a condition which + will force IMAPFolder.idle() method to return via StoreClosedException or FolderClosedException or simply return, thus allowing us to proceed with auto-reconnect. - Currently auto-reconnect will run infinitely making attempts to reconnect every 10 sec. + Currently auto-reconnect will run infinitely making attempts to reconnect every 10 sec. @@ -230,57 +230,57 @@ In the above example instead of relying on the default SearchTermStra overwrite="false"/>]]> - Finally, the <imap-idle-channel-adapter/> also accepts the 'error-channel' attribute. - If a downstream exception is thrown and an 'error-channel' is specified, - a MessagingException message containing the failed message and original exception, will be sent to this channel. - Otherwise, if the downstream channels are synchronous, any such exception will simply be logged as a + Finally, the <imap-idle-channel-adapter/> also accepts the 'error-channel' attribute. + If a downstream exception is thrown and an 'error-channel' is specified, + a MessagingException message containing the failed message and original exception, will be sent to this channel. + Otherwise, if the downstream channels are synchronous, any such exception will simply be logged as a warning by the channel adapter.
- +
Email Message Filtering - Very often you may encounter a requirement to filter incoming messages - (e.g., You want to only read emails that have 'Spring Integration' in the Subject line). This - could be easily accomplished by connecting Inbound Mail adapter with an expression-based Filter. Although it would work, there is a - downside to this approach. Since messages would be filtered after going through inbound mail adapter all such messages would be marked as read (SEEN) or - Un-read (depending on the value of should-mark-messages-as-read attribute). However in reality what would be more useful is to mark messages - as SEEN only if they passed the filtering criteria. This is very similar to looking at your email client while scrolling through all the + Very often you may encounter a requirement to filter incoming messages + (e.g., You want to only read emails that have 'Spring Integration' in the Subject line). This + could be easily accomplished by connecting Inbound Mail adapter with an expression-based Filter. Although it would work, there is a + downside to this approach. Since messages would be filtered after going through inbound mail adapter all such messages would be marked as read (SEEN) or + Un-read (depending on the value of should-mark-messages-as-read attribute). However in reality what would be more useful is to mark messages + as SEEN only if they passed the filtering criteria. This is very similar to looking at your email client while scrolling through all the messages in the preview pane, but only flagging messages as SEEN that were actually opened and read. - In Spring Integration 2.0.4 we've introduced mail-filter-expression attribute on inbound-channel-adapter and - imap-idle-channel-adapter. This attribute allows you to provide an expression which is a combination of SpEL and Regular Expression. + In Spring Integration 2.0.4 we've introduced mail-filter-expression attribute on inbound-channel-adapter and + imap-idle-channel-adapter. This attribute allows you to provide an expression which is a combination of SpEL and Regular Expression. For example if you would like to read only emails that contain 'Spring Integration' in the Subject line, you would configure mail-filter-expression attribute like this this: mail-filter-expression="subject matches '(?i).*Spring Integration.*" - Since javax.mail.internet.MimeMessage is the root context of SpEL Evaluation Context, you can filter on any value available - through MimeMessage including the actual body of the message. This one is particularly important since reading the body of the message would - typically result in such message to be marked as SEEN by default, but since we now setting PEAK flag of every incomming message to 'true', only + Since javax.mail.internet.MimeMessage is the root context of SpEL Evaluation Context, you can filter on any value available + through MimeMessage including the actual body of the message. This one is particularly important since reading the body of the message would + typically result in such message to be marked as SEEN by default, but since we now setting PEAK flag of every incomming message to 'true', only messages that were explicitly marked as SEEN will be seen as read. - + - So in the below example only messages that match the filter expression will be output by this adapter and only those messages will be marked as SEEN. - In this case based on the mail-filter-expression only messages that contain 'Spring Integration' in the subject line will be + So in the below example only messages that match the filter expression will be output by this adapter and only those messages will be marked as SEEN. + In this case based on the mail-filter-expression only messages that contain 'Spring Integration' in the subject line will be produced by this adapter. - + ]]> - Another reasonable question is what happens on the next poll, or idle event, or what happens when such adapter is restarted. - Will there be a potential duplication of massages to be filtered? In other words if on the last retrieval where you had 5 new messages and only 1 passed - the filter what would happen with the other 4. Would they go through the filtering logic again on the next poll or idle? After all they were not marked - as SEEN. The actual answer is no. They would not be subject of duplicate processing due to another flag (RECENT) that is set by the Email server and - is used by Spring Integration mail search filter. Folder implementations set this flag to indicate that this message is new to this folder, that is, - it has arrived since the last time this folder was opened. In other while our adapter may peek at the email it also lets the email server know that + Another reasonable question is what happens on the next poll, or idle event, or what happens when such adapter is restarted. + Will there be a potential duplication of massages to be filtered? In other words if on the last retrieval where you had 5 new messages and only 1 passed + the filter what would happen with the other 4. Would they go through the filtering logic again on the next poll or idle? After all they were not marked + as SEEN. The actual answer is no. They would not be subject of duplicate processing due to another flag (RECENT) that is set by the Email server and + is used by Spring Integration mail search filter. Folder implementations set this flag to indicate that this message is new to this folder, that is, + it has arrived since the last time this folder was opened. In other while our adapter may peek at the email it also lets the email server know that such email was touched and therefore will be marked as RECENT by the email server.
@@ -301,47 +301,47 @@ In the above example instead of relying on the default SearchTermStra Integration components, or invoke a custom bean to perform some action. For example, to move an IMAP message to a different folder after the transaction commits, you might use something similar to the following: - - + + - + - +]]> -public class Mover { + For the message to be still available for manipulation after the transaction, should-delete-messages diff --git a/src/reference/docbook/message-publishing.xml b/src/reference/docbook/message-publishing.xml index d5faf89418..45405ece6b 100644 --- a/src/reference/docbook/message-publishing.xml +++ b/src/reference/docbook/message-publishing.xml @@ -374,7 +374,7 @@ static class BankingOperationsImpl implements BankingOperations { - + ]]> diff --git a/src/reference/docbook/message-store.xml b/src/reference/docbook/message-store.xml index 342a759038..1a1a38297e 100644 --- a/src/reference/docbook/message-store.xml +++ b/src/reference/docbook/message-store.xml @@ -4,50 +4,50 @@ Message Store Enterprise Integration Patterns (EIP) identifies several patterns that have the capability to buffer messages. For example, - an Aggregator buffers messages until they can be released and a QueueChannel buffers - messages until consumers explicitly receive those messages from that channel. - Because of the failures that can occur at any point within your message flow, EIP components that buffer + an Aggregator buffers messages until they can be released and a QueueChannel buffers + messages until consumers explicitly receive those messages from that channel. + Because of the failures that can occur at any point within your message flow, EIP components that buffer messages also introduce a point where messages could be lost. - To mitigate the risk of losing Messages, EIP defines the Message Store pattern which allows + To mitigate the risk of losing Messages, EIP defines the Message Store pattern which allows EIP components to store Messages typically in some type of persistent store (e.g. RDBMS). - + - Spring Integration provides support for the Message Store pattern by + Spring Integration provides support for the Message Store pattern by a) defining a org.springframework.integration.store.MessageStore strategy interface, b) providing several implementations of this interface, and c) exposing a message-store attribute on all components that have the capability to buffer messages so that you can inject any instance that implements the MessageStore interface. - - Details on how to configure a specific Message Store implementation and/or how to inject - a MessageStore implementation into a specific buffering component are described - throughout the manual (see the specific component, such as QueueChannel, Aggregator, + + Details on how to configure a specific Message Store implementation and/or how to inject + a MessageStore implementation into a specific buffering component are described + throughout the manual (see the specific component, such as QueueChannel, Aggregator, Resequencer etc.), but here are a couple of samples to give you an idea: - + QueueChannel - -]]> + +]]> Aggregator - ]]> + ]]> - + By default Messages are stored in-memory using org.springframework.integration.store.SimpleMessageStore, an implementation of MessageStore. That might be fine for development or simple low-volume environments where the potential loss of non-persistent messages is not a concern. However, the typical production application will need a more robust option, not only to mitigate the risk of message loss but also to avoid potential out-of-memory errors. Therefore, we also provide MessageStore implementations for a variety of data-stores. Below is a complete list of supported implementations: - + - uses RDBMS to store Messages - uses Redis key/value datastore to store Messages diff --git a/src/reference/docbook/mongodb.xml b/src/reference/docbook/mongodb.xml index 3f8855fd01..4ebd182c5d 100644 --- a/src/reference/docbook/mongodb.xml +++ b/src/reference/docbook/mongodb.xml @@ -21,7 +21,7 @@ Connecting to MongoDb To begin interacting with MongoDB you first need to connect to it. Spring Integration builds on the support provided by another - Spring project, Spring Data MongoDB, which provides a factory + Spring project, Spring Data MongoDB, which provides a factory class called MongoDbFactory that simplifies integration with the MongoDB Client API. MongoDbFactory @@ -29,19 +29,19 @@ To connect to MongoDB you can use an implementation of the MongoDbFactory interface: - The example below shows SimpleMongoDbFactory, the out-of-the-box implementation: In Java: - + Or in Spring's XML configuration: - + @@ -69,7 +69,7 @@ As you can see SimpleMongoDbFactory takes two arguments: 1) a Mongo instance and 2) a String specifying the name of the database. If you need to configure properties such as host, port, etc, - you can pass those using one of the constructors provided by the underlying Mongo class. + you can pass those using one of the constructors provided by the underlying Mongo class. For more information on how to configure MongoDB, please refer to the Spring-Data-Document reference. @@ -82,10 +82,10 @@ As described in EIP, a Message Store allows you to persist Messages. This can be very useful when dealing with components that have a capability to buffer messages (QueueChannel, Aggregator, Resequencer, etc.) if reliability is a concern. - In Spring Integration, the MessageStore strategy also provides the foundation for the + In Spring Integration, the MessageStore strategy also provides the foundation for the ClaimCheck pattern, which is described in EIP as well. - + Spring Integration's MongoDB module provides the MongoDbMessageStore which is an implementation of both the MessageStore strategy (mainly used by the QueueChannel and ClaimCheck @@ -94,7 +94,7 @@ - + @@ -112,7 +112,7 @@ MongoDbFactory as a constructor argument.
- +
MongoDB Inbound Channel Adapter @@ -120,8 +120,8 @@ The MongoDb Inbound Channel Adapter is a polling consumer that reads data from MongoDb and sends it as a Message payload. - - As you can see from the configuration above, you configure a MongoDb Inbound Channel Adapter using - the inbound-channel-adapter element, providing values for various attributes such as: + the inbound-channel-adapter element, providing values for various attributes such as: - query or query-expression - a + query or query-expression - a JSON query (see MongoDb Querying) @@ -147,11 +147,11 @@ mongodb-factory - - reference to an instance of org.springframework.data.mongodb.MongoDbFactory + reference to an instance of o.s.data.mongodb.MongoDbFactory mongo-template - - reference to an instance of org.springframework.data.mongodb.core.MongoTemplate + reference to an instance of o.s.data.mongodb.core.MongoTemplate @@ -171,7 +171,7 @@ For example; you may want to move or remove a document after its been processed. You can do this using Transaction Synchronization feature that was added with Spring Integration 2.2. - - + -]]> +]]> -){ List documents = (List) target; @@ -198,12 +198,12 @@ } } } -}]]> +}]]> As you can see from the above, all you need to do is declare your poller to be transactional with a transactional element. This element can reference a real transaction manager (for example if some other part of your flow invokes JDBC). If you don't have a 'real' transaction, you can use a - org.springframework.integration.transaction.PseudoTransactionManager which is an implementation + org.springframework.integration.transaction.PseudoTransactionManager which is an implementation of Spring's PlatformTransactionManager and enables the use of the transaction synchronization features of the mongo adapter when there is no actual transaction. @@ -212,8 +212,8 @@ or after failure (rollback). - Once your poller is transactional all you need to do is set an instance of the - org.springframework.integration.transaction.TransactionSynchronizationFactory on the transactional element. + Once your poller is transactional all you need to do is set an instance of the + org.springframework.integration.transaction.TransactionSynchronizationFactory on the transactional element. TransactionSynchronizationFactory will create an instance of the TransactioinSynchronization. For your convenience, we've exposed a default SpEL-based TransactionSynchronizationFactory which allows you to configure SpEL expressions, with their execution being coordinated (synchronized) with a transaction. @@ -222,25 +222,25 @@ attributes. If only the channel attribute is present the received Message will be sent there as part of the particular synchronization scenario. If only the expression attribute is present and the result of an expression is a non-Null value, a Message with the result as the payload will be generated and sent to a default channel (NullChannel) and will appear in the - logs (DEBUG). If you want the evaluation result to go to a specific channel add a channel attribute. If the result of an + logs (DEBUG). If you want the evaluation result to go to a specific channel add a channel attribute. If the result of an expression is null or void, no Message will be generated. For more information about transaction synchronization, see .
- +
MongoDB Outbound Channel Adapter The MongoDb Outbound Channel Adapter allows you to write the Message payload to a MongoDb document store - - ]]> + mongodb-factory="mongoDbFactory" />]]> As you can see from the configuration above, you configure a MongoDb Outbound Channel Adapter using @@ -252,16 +252,16 @@ mongo-converter - - reference to an instance of org.springframework.data.mongodb.core.convert.MongoConverter to assist with + reference to an instance of o.s.data.mongodb.core.convert.MongoConverter to assist with converting a raw java object to a JSON document representation mongodb-factory - - reference to an instance of org.springframework.data.mongodb.MongoDbFactory + reference to an instance of o.s.data.mongodb.MongoDbFactory mongo-template - - reference to an instance of org.springframework.data.mongodb.core.MongoTemplate + reference to an instance of o.s.data.mongodb.core.MongoTemplate (NOTE: you can not have both mongo-template and mongodb-factory set) diff --git a/src/reference/docbook/redis.xml b/src/reference/docbook/redis.xml index 6092075dbf..129d716e8a 100644 --- a/src/reference/docbook/redis.xml +++ b/src/reference/docbook/redis.xml @@ -20,19 +20,19 @@
Connecting to Redis - + To begin interacting with Redis you first need to connect to it. Spring Integration uses support provided by another Spring project, Spring Data Redis, which provides typical Spring constructs: ConnectionFactory and Template. Those abstractions - simplify integration with several Redis-client Java APIs. Currently Spring-Data-Redis supports + simplify integration with several Redis-client Java APIs. Currently Spring-Data-Redis supports jedis, jredis and rjc - + RedisConnectionFactory To connect to Redis you would use one of the implementations of the RedisConnectionFactory interface: - - + The example below shows how to create a JedisConnectionFactory. - + In Java: - - + Or in Spring's XML configuration: - - + + ]]> - + The implementations of RedisConnectionFactory provide a set of properties such as port and host that can be set if needed. Once an instance of RedisConnectionFactory is created, you can create an instance of RedisTemplate and inject it with the RedisConnectionFactory. RedisTemplate - + As with other template classes in Spring (e.g., JdbcTemplate, JmsTemplate) RedisTemplate is a helper class that simplifies Redis data access code. @@ -73,12 +74,12 @@ jcf.afterPropertiesSet();]]> The code below shows how to create an instance of RedisTemplate: In Java: - (); + (); rt.setConnectionFactory(redisConnectionFactory);]]> - + Or in Spring's XML configuration:: - + ]]> @@ -88,7 +89,7 @@ rt.setConnectionFactory(redisConnectionFactory);]]> Messaging with Redis - As mentioned in the introduction Redis provides support for Publish-Subscribe messaging via its PUBLISH, SUBSCRIBE and UNSUBSCRIBE + As mentioned in the introduction Redis provides support for Publish-Subscribe messaging via its PUBLISH, SUBSCRIBE and UNSUBSCRIBE commands. As with JMS and AMQP, Spring Integration provides Message Channels and adapters for sending and receiving messages via Redis. @@ -96,14 +97,14 @@ rt.setConnectionFactory(redisConnectionFactory);]]> Redis Publish/Subscribe channel - Similar to the JMS there are cases where both the producer and consumer are intended to be part of the same application, running - within the same process. This could be accomplished by using a pair of inbound and outbound Channel Adapters, + Similar to the JMS there are cases where both the producer and consumer are intended to be part of the same application, running + within the same process. This could be accomplished by using a pair of inbound and outbound Channel Adapters, however just like with Spring Integration's JMS support, there is a simpler approach to address this use case. - ]]> + ]]> - The publish-subscribe-channel (above) will behave much like a normal <publish-subscribe-channel/> element from the + The publish-subscribe-channel (above) will behave much like a normal <publish-subscribe-channel/> element from the main Spring Integration namespace. It can be referenced by both input-channel and output-channel attributes of any endpoint. The difference is that this channel is backed by a Redis topic name - a String value specified by the topic-name attribute. However unlike JMS this topic doesn't have to be created in advance or even auto-created by Redis. In Redis topics are simple @@ -120,16 +121,17 @@ rt.setConnectionFactory(redisConnectionFactory);]]> Redis Inbound Channel Adapter The Redis-based Inbound Channel Adapter adapts incoming Redis messages into Spring Integration Messages in the same way as other - inbound adapters. It receives platform-specific messages (Redis in this case) and converts them to Spring Integration Messages using + inbound adapters. It receives platform-specific messages (Redis in this case) and converts them to Spring Integration Messages using a MessageConverter strategy. - - + @@ -137,35 +139,36 @@ rt.setConnectionFactory(redisConnectionFactory);]]> - Above is a simple but complete configuration of a Redis Inbound Channel Adapter. Note that the above configuration relies on the + Above is a simple but complete configuration of a Redis Inbound Channel Adapter. Note that the above configuration relies on the familiar Spring paradigm of auto-discovering certain beans. In this case the redisConnectionFactory is implicitly injected into the adapter. You can of course specify it explicitly using the connection-factory attribute instead. Also, note that the above configuration injects the adapter with a custom MessageConverter. - The approach is similar to JMS where MessageConverters are used to convert between + The approach is similar to JMS where MessageConverters are used to convert between Redis Messages and the Spring Integration Message payloads. The default is a SimpleMessageConverter. Inbound adapters can subscribe to multiple topic names hence the comma-delimited set of values in the topics attribute.
- +
Redis Outbound Channel Adapter - The Redis-based Outbound Channel Adapter adapts outgoing Spring Integration messages into Redis messages in the same way as + The Redis-based Outbound Channel Adapter adapts outgoing Spring Integration messages into Redis messages in the same way as other outbound adapters. It receives Spring Integration messages and converts them to platform-specific messages (Redis in this case) using a MessageConverter strategy. - + - - + + ]]> @@ -173,19 +176,19 @@ rt.setConnectionFactory(redisConnectionFactory);]]> As you can see the configuration is similar to the Redis Inbound Channel Adapter. The adapter is implicitly injected with a RedisConnectionFactory which was defined with 'redisConnectionFactory' as its bean name. - This example also includes the optional, custom MessageConverter (the 'testConverter' bean). + This example also includes the optional, custom MessageConverter (the 'testConverter' bean).
Redis Message Store - + As described in EIP, a Message Store allows you to persist Messages. This can be very useful when dealing with components that have a capability to buffer messages (QueueChannel, Aggregator, Resequencer, etc.) if reliability is a concern. - In Spring Integration, the MessageStore strategy also provides the foundation for the + In Spring Integration, the MessageStore strategy also provides the foundation for the ClaimCheck pattern, which is described in EIP as well. @@ -197,7 +200,7 @@ rt.setConnectionFactory(redisConnectionFactory);]]> - + @@ -220,7 +223,7 @@ rt.setConnectionFactory(redisConnectionFactory);]]> the valueSerializer property of the RedisMessageStore.
- +
RedisStore Inbound Channel Adapter @@ -229,35 +232,26 @@ rt.setConnectionFactory(redisConnectionFactory);]]> from a Redis collection and sends it as a Message payload. - - -]]> + + +]]> As you can see from the configuration above you configure a Redis Store Inbound Channel Adapter using - the store-inbound-channel-adapter element, providing values for various attributes such as: - - - key or key-expression - The name of the key for the collection being used. - - - collection-type - enumeration of the Collection types supported by this adapter. Supported Collections are: LIST, SET, ZSET, PROPERTIES, MAP - - - connection-factory - - reference to an instance of org.springframework.data.redis.connection.RedisConnectionFactory - - - redis-template - - reference to an instance of org.springframework.data.redis.core.RedisTemplate - - + the store-inbound-channel-adapter element, providing values for various attributes such as: + + + key or key-expression - The name of the key for the collection being used. + collection-type - enumeration of the Collection types supported by this adapter. Supported Collections are: LIST, SET, ZSET, PROPERTIES, MAP + connection-factory - reference to an instance of o.s.data.redis.connection.RedisConnectionFactory + redis-template - reference to an instance of o.s.data.redis.core.RedisTemplate - and other attributes that are common across all other inbound adapters (e.g., 'channel'). + + and other attributes that are common across all other inbound adapters (e.g., 'channel'). You cannot set both redis-template and connection-factory. @@ -270,14 +264,14 @@ rt.setConnectionFactory(redisConnectionFactory);]]> For example, if the store is written to using a RedisStore Outbound Adapter that has its extract-payload-elements set to false, you must provide a RedisTemplate configured thus: - - - - - - - - + + + + + + + + ]]> This uses String serializers for keys and hash keys and the default JDK Serialization serializers for @@ -292,9 +286,9 @@ rt.setConnectionFactory(redisConnectionFactory);]]> Also, you may wish to perform some post-processing to the successfully processed data that was read from the Redis collection. For example; you may want to move or remove the value after its been processed. - You can do this using the Transaction Synchronization feature that was added with Spring Integration 2.2. + You can do this using the Transaction Synchronization feature that was added with Spring Integration 2.2. - -]]> +]]> As you can see from the above all, you need to do is declare your poller to be transactional with a transactional element. This element can reference a real transaction manager (for example if some other part of your flow invokes JDBC). If you don't have a 'real' transaction, you can use a - org.springframework.integration.transaction.PseudoTransactionManager which is an implementation + o.s.i.transaction.PseudoTransactionManager which is an implementation of Spring's PlatformTransactionManager and enables the use of the transaction synchronization features of the redis adapter when there is no actual transaction. @@ -326,7 +320,7 @@ rt.setConnectionFactory(redisConnectionFactory);]]> Once your poller is transactional all you need to do is set an instance of the - org.springframework.integration.transaction.TransactionSynchronizationFactory on the transactional element. + org.springframework.integration.transaction.TransactionSynchronizationFactory on the transactional element. TransactionSynchronizationFactory will create an instance of the TransactionSynchronization. For your convenience we've exposed a default SpEL-based TransactionSynchronizationFactory which allows you to configure SpEL expressions, with their execution being coordinated (synchronized) with a transaction. @@ -342,7 +336,7 @@ rt.setConnectionFactory(redisConnectionFactory);]]> For more information about transaction synchronization, see .
- +
RedisStore Outbound Channel Adapter @@ -350,48 +344,37 @@ rt.setConnectionFactory(redisConnectionFactory);]]> The RedisStore Outbound Channel Adapter allows you to write a Message payload to a Redis collection - ]]> + key="myCollection" />]]> As you can see from the configuration above, you configure a Redis Store Outbound Channel Adapter using - the store-inbound-channel-adapter element, providing values for various attributes such as: + the store-inbound-channel-adapter element, providing values for various attributes such as: + - - key or key-expression - The name of the key for the collection being used. - - - extract-payload-elements - If set to true (Default) and the payload is an instance of a "multi- + key or key-expression - The name of the key for the collection being used. + extract-payload-elements - If set to true (Default) and the payload is an instance of a "multi- value" object (i.e., Collection or Map) it will be stored using addAll/ - putAll semantics. Otherwise, if set to false the payload will be stored - as a single entry regardless of its type. If the payload is not an instance - of a "multi-value" object, the value of this attribute is ignored and the - payload will always be stored as a single entry. - - - collection-type - enumeration of the Collection types supported by this adapter. Supported Collections are: LIST, SET, ZSET, PROPERTIES, MAP - - - map-key-expression - SpEL expression that returns the name of the key for entry being + putAll semantics. Otherwise, if set to false the payload will be stored + as a single entry regardless of its type. If the payload is not an instance + of a "multi-value" object, the value of this attribute is ignored and the + payload will always be stored as a single entry. + collection-type - enumeration of the Collection types supported by this adapter. Supported Collections are: LIST, SET, ZSET, PROPERTIES, MAP + map-key-expression - SpEL expression that returns the name of the key for entry being stored. Only applies if the collection-type is MAP or PROPERTIES and - 'extract-payload-elements' is false. - - - connection-factory - - reference to an instance of org.springframework.data.redis.connection.RedisConnectionFactory - - - redis-template - - reference to an instance of org.springframework.data.redis.core.RedisTemplate - + 'extract-payload-elements' is false. + connection-factory - reference to an instance of o.s.data.redis.connection.RedisConnectionFactory + redis-template - reference to an instance of o.s.data.redis.core.RedisTemplate + and other attributes that are common across all other inbound adapters (e.g., 'channel'). + You cannot set both redis-template and connection-factory. - + By default, the adapter uses a StringRedisTemplate; this uses StringRedisSerializers for keys, values, hash keys and hash values. However, if diff --git a/src/reference/docbook/rmi.xml b/src/reference/docbook/rmi.xml index 648e17735a..f29924550b 100644 --- a/src/reference/docbook/rmi.xml +++ b/src/reference/docbook/rmi.xml @@ -17,11 +17,10 @@ To configure the outbound gateway write a bean definition like this: - + - ]]> - +]]>
@@ -29,10 +28,9 @@ Inbound RMI To receive messages over RMI you need to use a RmiInboundGateway. This gateway can be configured like this - - - ]]> - + + +]]>
@@ -40,26 +38,26 @@ RMI namespace support To configure the inbound gateway you can choose to use the namespace support for it. The following code snippet shows the different configuration options that are supported. - + - + - + - + - ]]> +]]> To configure the outbound gateway you can use the namespace support as well. The following code snippet shows the different configuration for an outbound rmi gateway. - ]]> + ]]> diff --git a/src/reference/docbook/samples.xml b/src/reference/docbook/samples.xml index aa332ca912..b78cf406ed 100644 --- a/src/reference/docbook/samples.xml +++ b/src/reference/docbook/samples.xml @@ -26,18 +26,18 @@
Where to get Samples - The Spring Integration Samples project is hosted on GitHub. + The Spring Integration Samples project is hosted on GitHub. You can find the repository at: https://github.com/SpringSource/spring-integration-samples - In order to check out or clone (Git parlance) the samples, - please make sure you have a Git client installed on your system. - There are several GUI-based products available for many platforms, e.g. - EGit for the Eclipse IDE. - A simple Google search will help you find them. Of course you can also just + In order to check out or clone (Git parlance) the samples, + please make sure you have a Git client installed on your system. + There are several GUI-based products available for many platforms, e.g. + EGit for the Eclipse IDE. + A simple Google search will help you find them. Of course you can also just use the command line interface for Git. @@ -45,48 +45,48 @@ http://git-scm.com/. - In order to checkout (clone in Git terms) the Spring Integration samples + In order to checkout (clone in Git terms) the Spring Integration samples repository using the Git command line tool, issue the following commands: - + - That is all you need to do in order to clone the entire samples repository - into a directory named spring-integration-samples within + That is all you need to do in order to clone the entire samples repository + into a directory named spring-integration-samples within the working directory where you issued that git command. - Since the samples repository is a live repository, you might want to perform - periodic pulls (updates) to get new samples, as well as updates to - the existing samples. In order to do so issue the following git + Since the samples repository is a live repository, you might want to perform + periodic pulls (updates) to get new samples, as well as updates to + the existing samples. In order to do so issue the following git PULL command: - +
- Submitting Samples or Sample Requests + Submitting Samples or Sample Requests How can I contribute my own Samples? - Github is for social coding: if you want to submit your own code examples - to the Spring Integration Samples project, we encourage contributions - through pull - requests from - forks - of this repository. If you want to contribute code this way, please - reference, if possible, a - JIRA Ticket + Github is for social coding: if you want to submit your own code examples + to the Spring Integration Samples project, we encourage contributions + through pull + requests from + forks + of this repository. If you want to contribute code this way, please + reference, if possible, a + JIRA Ticket that provides some details regarding the provided sample. Sign the contributor license agreement - Very important: before we can accept your Spring Integration sample, - we will need you to sign the SpringSource contributor license agreement (CLA). - Signing the contributor's agreement does not grant anyone commit rights - to the main repository, but it does mean that we can accept your + Very important: before we can accept your Spring Integration sample, + we will need you to sign the SpringSource contributor license agreement (CLA). + Signing the contributor's agreement does not grant anyone commit rights + to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. In order to read and sign the CLA, please go to: @@ -94,33 +94,33 @@ - As Project, please select Spring Integration. + As Project, please select Spring Integration. The Project Lead is Mark Fisher. Code Contribution Process - For the actual code contribution process, please read the the - Contributor Guidelines for Spring Integration, + For the actual code contribution process, please read the the + Contributor Guidelines for Spring Integration, they apply for this project as well: - This process ensures that every commit gets peer-reviewed. As a matter of + This process ensures that every commit gets peer-reviewed. As a matter of fact, the core committers follow the exact same rules. We are gratefully looking forward to your Spring Integration Samples! - + Sample Requests - + - As mentioned earlier, the Spring Integration Samples - project has a dedicated JIRA Issue tracking system. To submit new sample + As mentioned earlier, the Spring Integration Samples + project has a dedicated JIRA Issue tracking system. To submit new sample requests, please visit our JIRA Issue Tracking system: - + https://jira.springframework.org/browse/INTSAMPLES. @@ -128,7 +128,7 @@
Samples Structure - Starting with Spring Integration 2.0, the structure of the samples + Starting with Spring Integration 2.0, the structure of the samples changed as well. With plans for more samples we realized that some samples have different goals than others. While they all share the common goal of showing you how to apply and work with the Spring Integration framework, they also differ in areas where some samples are meant to concentrate on a technical @@ -443,7 +443,7 @@ That includes Samples; so, if you can't find what you are looking for, let us kn This and other samples in this section are built on top of Enterprise Integration Patterns and can be considered "building blocks" - for YOUR solution; they are not intended to be complete solutions. Integration concerns exist in all types of application + for YOUR solution; they are not intended to be complete solutions. Integration concerns exist in all types of application (whether server based or not). It should not require change in design, testing and deployment strategy if such applications need to be integrated. @@ -480,129 +480,129 @@ That includes Samples; so, if you can't find what you are looking for, let us kn Here is the XML configuration: + - + - + - - + + - - + + - - - - + + - - - - + + - - + + - + - + - + - + + - + - - - ]]> +]]> + As you can see, each Message Endpoint is connected to input and/or output channels. Each endpoint will manage its own Lifecycle (by default endpoints start automatically upon initialization - to prevent that add the "auto-startup" attribute with a value of "false"). Most importantly, notice that the objects are simple POJOs with strongly typed method arguments. For example, here is the Splitter: + split(Order order) { - return order.getItems(); - } - }]]> + public List split(Order order) { + return order.getItems(); + } +}]]> + In the case of the Router, the return value does not have to be a MessageChannel instance (although it can be). As you see in this example, a String-value representing the channel name is returned instead. + - + public String resolveOrderItemChannel(OrderItem orderItem) { + return (orderItem.isIced()) ? "coldDrinks" : "hotDrinks"; + } +}]]> Now turning back to the XML, you see that there are two <service-activator> elements. Each of these is delegating to the same Barista instance but different methods: 'prepareHotDrink' or 'prepareColdDrink' corresponding to the two channels where order items have been routed. + - + public Drink prepareColdDrink(OrderItem orderItem) { + try { + Thread.sleep(this.coldDrinkDelay); + System.out.println(Thread.currentThread().getName() + + " prepared cold drink #" + coldDrinkCounter.incrementAndGet() + + " for order #" + orderItem.getOrder().getNumber() + ": " + + orderItem); + return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), + orderItem.isIced(), orderItem.getShots()); + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return null; + } + } +}]]> As you can see from the code excerpt above, the barista methods have different delays (the hot drinks take 5 times as long to prepare). This simulates work being completed at different rates. When the @@ -611,30 +611,32 @@ That includes Samples; so, if you can't find what you are looking for, let us kn interface. Above, you will see that the <gateway> element is specified in the configuration file. This triggers the creation of a proxy that implements the given 'service-interface' and connects it to a channel. The channel name is provided on the @Gateway annotation of the Cafe interface. - public interface Cafe { - - @Gateway(requestChannel="orders") - void placeOrder(Order order); - - } - Finally, have a look at the main() method of the CafeDemo itself. - 0) { - context = new FileSystemXmlApplicationContext(args); - } - else { - context = new ClassPathXmlApplicationContext("cafeDemo.xml", CafeDemo.class); - } - Cafe cafe = context.getBean("cafe", Cafe.class); - for (int i = 1; i <= 100; i++) { - Order order = new Order(i); - order.addItem(DrinkType.LATTE, 2, false); - order.addItem(DrinkType.MOCHA, 3, true); - cafe.placeOrder(order); - } - }]]> + public interface Cafe { + + @Gateway(requestChannel="orders") + void placeOrder(Order order); + +} + + Finally, have a look at the main() method of the CafeDemo itself. + + 0) { + context = new FileSystemXmlApplicationContext(args); + } + else { + context = new ClassPathXmlApplicationContext("cafeDemo.xml", CafeDemo.class); + } + Cafe cafe = context.getBean("cafe", Cafe.class); + for (int i = 1; i <= 100; i++) { + Order order = new Order(i); + order.addItem(DrinkType.LATTE, 2, false); + order.addItem(DrinkType.MOCHA, 3, true); + cafe.placeOrder(order); + } +}]]> To run this sample as well as 8 others, refer to the README.txt within the "samples" directory of the main distribution as described at the beginning of this chapter. @@ -645,6 +647,7 @@ That includes Samples; so, if you can't find what you are looking for, let us kn This is to be expected based on their respective delays of 1000 and 5000 milliseconds. However, by configuring a poller with a concurrent task executor, you can dramatically change the results. For example, you could use a thread pool executor with 5 workers for the hot drink barista while keeping the cold drink barista as it is: + ]]>]]> - Also, notice that the worker thread name is displayed with each invocation. You will see that the hot drinks are prepared by the task-executor threads. If you provide a much shorter poller interval (such as 100 milliseconds), @@ -684,10 +686,9 @@ That includes Samples; so, if you can't find what you are looking for, let us kn the XPath splitter component. - - - ]]> + ]]> A service activator is then used to pass the message into a stock checker POJO. The order item document is enriched with information @@ -697,16 +698,14 @@ That includes Samples; so, if you can't find what you are looking for, let us kn - - ]]> +]]> Where the order item is not in stock the message is transformed using xslt into a format suitable for sending to the supplier. - - ]]> + xsl-resource="classpath:org/springframework/integration/samples/xml/bigBooksSupplierTransformer.xsl"/>]]>
diff --git a/src/reference/docbook/service-activator.xml b/src/reference/docbook/service-activator.xml index 4f74ef6d99..ecb3c3d5e7 100644 --- a/src/reference/docbook/service-activator.xml +++ b/src/reference/docbook/service-activator.xml @@ -32,7 +32,7 @@ message to an appropriate reply channel. To determine the reply channel, it will first check if an "output-channel" was provided in the endpoint configuration: <int:service-activator input-channel="exampleChannel" output-channel="replyChannel" - ref="somePojo" method="someMethod"/> + ref="somePojo" method="someMethod"/>
If no "output-channel" is available, it will then check the Message's replyChannel header value. If that value is available, it will then check its type. If it is a MessageChannel, the reply message will be sent to that channel. If it is a @@ -68,35 +68,35 @@ configuration is not allowed, as it creates an ambiguous condition and will result in an Exception being thrown. - + Service Activators and the Spring Expression Language (SpEL) - + - Since Spring Integration 2.0, Service Activators can also benefit from SpEL + Since Spring Integration 2.0, Service Activators can also benefit from SpEL (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html). - For example, you may now invoke any bean method without pointing to the bean via a ref attribute or including it as an + For example, you may now invoke any bean method without pointing to the bean via a ref attribute or including it as an inner bean definition. For example: - - - + ]]> - + In the above configuration instead of injecting 'accountService' using a ref or as an inner bean, we are simply using SpEL's @beanId notation and invoking a method which takes a type compatible with Message payload. We are also passing a header value. As you can see, any valid SpEL expression can be evaluated against any content in the Message. - For simple scenarios your Service Activators do not even have to reference a bean if all logic can be encapsulated + For simple scenarios your Service Activators do not even have to reference a bean if all logic can be encapsulated by such an expression. - + ]]> In the above configuration our service logic is to simply multiply the payload value by 2, and SpEL lets us handle it relatively easy. - + - + diff --git a/src/reference/docbook/sftp.xml b/src/reference/docbook/sftp.xml index 72214bf3ef..91d1610838 100644 --- a/src/reference/docbook/sftp.xml +++ b/src/reference/docbook/sftp.xml @@ -25,8 +25,7 @@ + http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd"]]> diff --git a/src/reference/docbook/splitter.xml b/src/reference/docbook/splitter.xml index d9085945f7..d2d7d6d31e 100644 --- a/src/reference/docbook/splitter.xml +++ b/src/reference/docbook/splitter.xml @@ -16,7 +16,7 @@ Programming model The API for performing splitting consists of one base class, - AbstractMessageSplitter, which is a + AbstractMessageSplitter, which is a MessageHandler implementation, encapsulating features which are common to splitters, such as filling in the appropriate message headers CORRELATION_ID, SEQUENCE_SIZE, and @@ -24,28 +24,28 @@ down the messages and the results of their processing (in a typical scenario, these headers would be copied over to the messages that are produced by the various transforming endpoints), and use them, for - example, in a + example, in a Composed Message Processor scenario. An excerpt from AbstractMessageSplitter can be seen below: - public abstract class AbstractMessageSplitter - extends AbstractReplyProducingMessageConsumer { - ... - protected abstract Object splitMessage(Message<?> message); + message); -} +}]]> - To implement a specific Splitter in an application, + To implement a specific Splitter in an application, extend AbstractMessageSplitter and implement the splitMessage method, which contains logic for splitting the messages. The return value may be one of the following: - a Collection (or subclass thereof) or an array of - Message objects - + a Collection (or subclass thereof) or an array of + Message objects - in this case the messages will be sent as such (after the CORRELATION_ID, SEQUENCE_SIZE and SEQUENCE_NUMBER are populated). Using this approach gives more control to the developer, for example @@ -106,7 +106,7 @@ above .Optional. If reference to a bean is not provided, then it is assumed that the payload of the Message that arrived on the input-channel is - an implementation of java.util.Collection + an implementation of java.util.Collection and the default splitting logic will be applied to the Collection, incorporating each individual element into a Message and sending it to the output-channel. @@ -152,7 +152,7 @@ The @Splitter annotation is applicable to methods that expect either the Message type or the message payload type, - and the return values of the method should be a Collection of any type. + and the return values of the method should be a Collection of any type. If the returned values are not actual Message objects, then each item will be wrapped in a Message as its payload. Each message will be sent to the designated output channel for the endpoint diff --git a/src/reference/docbook/stream.xml b/src/reference/docbook/stream.xml index 503e105f79..b0fef95c0b 100644 --- a/src/reference/docbook/stream.xml +++ b/src/reference/docbook/stream.xml @@ -72,20 +72,22 @@ To configure the inbound channel adapter the following code snippet shows the different configuration options that are supported. + ]]> - To configure the outbound channel adapter you can use the namespace support as well. The following code snippet shows the different configuration for an outbound channel adapters. - + + - + - - ]]> - +]]> diff --git a/src/reference/docbook/transactions.xml b/src/reference/docbook/transactions.xml index 26e38766df..5f8e656393 100644 --- a/src/reference/docbook/transactions.xml +++ b/src/reference/docbook/transactions.xml @@ -189,18 +189,18 @@ as a convinience. Key strategy interfaces for this feature are - @@ -229,19 +229,19 @@ public interface TransactionSynchronizationProcessor { To simplify configuration of these components, namespace support for the default factory has been provided. Configuration is best described using an example: - - - - + + + + - - + + ]]> The result of the SpEL evaluation is sent as the payload to either the committedChannel @@ -261,10 +261,10 @@ public interface TransactionSynchronizationProcessor { followed by the synchronized action. - It is also important to understand that if you provide a custom TransactionSynchronizationFactory, - it is responsible for creating a resource synchronization that will cause the bound resource to be unbound automatically, - when the transaction completes. - The default TransactionSynchronizationFactory does this by returning a subclass + It is also important to understand that if you provide a custom TransactionSynchronizationFactory, + it is responsible for creating a resource synchronization that will cause the bound resource to be unbound automatically, + when the transaction completes. + The default TransactionSynchronizationFactory does this by returning a subclass of ResourceHolderSynchronization, with the default shouldUnbindAtCompletion() returning true. @@ -296,6 +296,6 @@ public interface TransactionSynchronizationProcessor { To use a PseudoTransactionManager, simply define it as a <bean/>, in the same way you would configure a real transaction manager: - ]]> + ]]> diff --git a/src/reference/docbook/transformer.xml b/src/reference/docbook/transformer.xml index 57630baf00..82543517ee 100644 --- a/src/reference/docbook/transformer.xml +++ b/src/reference/docbook/transformer.xml @@ -26,11 +26,11 @@ - +
Configuring Transformer - - + +
Configuring Transformer with XML @@ -69,29 +69,29 @@ Returning null will result in an exception since a Message Transformer should always be expected to transform each source Message into a valid target Message. In other words, a Message Transformer should not be used as a Message Filter since there is a dedicated <filter> option for that. However, if you do need this type of - behavior (where a component might return NULL and that should not be considered an error), a + behavior (where a component might return NULL and that should not be considered an error), a service-activator could be used. Its requires-reply value is FALSE by default, but that can be set to TRUE in order to have Exceptions thrown for NULL return values as with the transformer. - + Transformers and Spring Expression Language (SpEL) - + Just like Routers, Aggregators and other components, as of Spring Integration 2.0 Transformers can also benefit from SpEL support (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/expressions.html) whenever transformation logic is relatively simple. - - ]]> - - In the above configuration we are achieving a simple transformation of the payload with a simple SpEL - expression and without writing a custom transformer. Our payload (assuming String) will be + + In the above configuration we are achieving a simple transformation of the payload with a simple SpEL + expression and without writing a custom transformer. Our payload (assuming String) will be upper-cased and concatenated with the current timestamp with some simple formatting. - + Common Transformers @@ -101,7 +101,7 @@ ObjectToStringTransformer whose output is a Message with a String payload. That String is the result of invoking the toString() operation on the inbound Message's payload. - ]]> + ]]> A potential example for this would be sending some arbitrary object to the 'outbound-channel-adapter' in the file namespace. Whereas that Channel Adapter only supports String, byte-array, or @@ -136,9 +136,9 @@ by default, but you can provide an implementation of Spring 3.0's Serializer or Deserializer strategies via the 'serializer' and 'deserializer' attributes, respectively. - + - ]]> +]]> Object-to-Map Transformer @@ -209,7 +209,7 @@ public class Kid { JSON Transformers - Object to JSON and JSON to Object transformers are provided. + Object to JSON and JSON to Object transformers are provided. ]]> @@ -231,7 +231,7 @@ public class Kid { - ]]> + ]]> The second solution is to eliminate the json transformers altogether and use an @@ -304,7 +304,8 @@ public class Kid { how to configure the message converter; it requires spring-amqp 1.1.3 or above. - +
- +
- - + +
Header Filter - + Some times your transformation use case might be as simple as removing a few headers. For such a use case, Spring Integration provides a Header Filter which allows you to specify certain header names that should be removed from the output Message (e.g. for security reasons or a value that was only needed temporarily). - Basically the Header Filter is the opposite of the Header Enricher. + Basically the Header Filter is the opposite of the Header Enricher. The latter is discussed in - - ]]> - + As you can see, configuration of a Header Filter is quite simple. It is a typical endpoint with input/output channels and a header-names attribute. That attribute accepts the names of the header(s) (delimited by commas if there are multiple) that need to be removed. So, in the above example the headers named 'lastName' and 'state' will not be present on the outbound Message. diff --git a/src/reference/docbook/twitter.xml b/src/reference/docbook/twitter.xml index 68e5812ea3..9ef950b015 100644 --- a/src/reference/docbook/twitter.xml +++ b/src/reference/docbook/twitter.xml @@ -4,7 +4,7 @@ Twitter Adapter - Spring Integration provides support for interacting with Twitter. With the Twitter adapters you can both + Spring Integration provides support for interacting with Twitter. With the Twitter adapters you can both receive and send Twitter messages. You can also perform a Twitter search based on a schedule and publish the search results within Messages. @@ -12,13 +12,13 @@
Introduction - Twitter is a social networking and micro-blogging service that enables its users to send and read messages known as tweets. - Tweets are text-based posts of up to 140 characters displayed on the author's profile page and delivered to the author's + Twitter is a social networking and micro-blogging service that enables its users to send and read messages known as tweets. + Tweets are text-based posts of up to 140 characters displayed on the author's profile page and delivered to the author's subscribers who are known as followers. - Previous versions of Spring Integration were dependent upon the Twitter4J API, + Previous versions of Spring Integration were dependent upon the Twitter4J API, but with the release of Spring Social 1.0 GA, Spring Integration, as of version 2.1, now builds directly upon Spring Social's Twitter support, instead of Twitter4J. @@ -28,23 +28,23 @@ Spring Integration provides a convenient namespace configuration to define Twitter artifacts. You can enable it by adding the following within your XML header.
- +
Twitter OAuth Configuration - + - The Twitter API allows for both authenticated and anonymous operations. For authenticated operations Twitter uses OAuth - - an authentication protocol that allows users to approve an application to act on their behalf without - sharing their password. More information can be found at http://oauth.net/ or - in this article http://hueniverse.com/oauth/ from Hueniverse. - Please also see OAuth FAQ for more information about OAuth and Twitter. + The Twitter API allows for both authenticated and anonymous operations. For authenticated operations Twitter uses OAuth + - an authentication protocol that allows users to approve an application to act on their behalf without + sharing their password. More information can be found at http://oauth.net/ or + in this article http://hueniverse.com/oauth/ from Hueniverse. + Please also see OAuth FAQ for more information about OAuth and Twitter. - In order to use OAuth authentication/authorization with Twitter you must create a new Application on the Twitter Developers site. + In order to use OAuth authentication/authorization with Twitter you must create a new Application on the Twitter Developers site. Follow the directions below to create a new application and obtain consumer keys and an access token: @@ -53,105 +53,105 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/twitter Go to http://dev.twitter.com/ - Click on the Register an app link and fill out all required fields on the form provided; - set Application Type to Client and depending on the nature of your application select - Default Access Type as Read & Write or Read-only - and Submit the form. If everything is successful you'll be presented with the Consumer Key + Click on the Register an app link and fill out all required fields on the form provided; + set Application Type to Client and depending on the nature of your application select + Default Access Type as Read & Write or Read-only + and Submit the form. If everything is successful you'll be presented with the Consumer Key and Consumer Secret. Copy both values in a safe place. - On the same page you should see a My Access Token button on the side bar (right). - Click on it and you'll be presented with two more values: Access Token and Access Token Secret. + On the same page you should see a My Access Token button on the side bar (right). + Click on it and you'll be presented with two more values: Access Token and Access Token Secret. Copy these values in a safe place as well. - +
Twitter Template As mentioned above, Spring Integration relies upon Spring Social, and that library provides an implementation of the template - pattern, org.springframework.social.twitter.api.impl.TwitterTemplate to interact with Twitter. + pattern, o.s.social.twitter.api.impl.TwitterTemplate to interact with Twitter. For anonymous operations (e.g., search), you don't have to define an instance of TwitterTemplate explicitly, since a default instance will be created and injected into the endpoint. However, for authenticated operations - (update status, send direct message, etc.), you must configure a TwitterTemplate as a bean and + (update status, send direct message, etc.), you must configure a TwitterTemplate as a bean and inject it explicitly into the endpoint, because the authentication configuration is required. Below is a sample configuration of TwitterTemplate: - + ]]> The values above are not real. - - As you can see from the configuration above, all we need to do is to provide + + As you can see from the configuration above, all we need to do is to provide OAuth attributes as constructor arguments. The values would be those you obtained in the previous step. The order of constructor arguments is: 1) consumerKey, 2) consumerSecret, 3) accessToken, and 4) accessTokenSecret. - A more practical way to manage OAuth connection attributes would be via Spring's property placeholder support by simply + A more practical way to manage OAuth connection attributes would be via Spring's property placeholder support by simply creating a property file (e.g., oauth.properties): - + - Then, you can configure a property-placeholder to point to the above property file: + + Then, you can configure a property-placeholder to point to the above property file: + + - - - - - - - + + + + + ]]> - +
- +
Twitter Inbound Adapters - Twitter inbound adapters allow you to receive Twitter Messages. There are several types of + Twitter inbound adapters allow you to receive Twitter Messages. There are several types of twitter messages, or tweets - The current release of Spring Integration provides support for receiving tweets as Timeline Updates, + The current release of Spring Integration provides support for receiving tweets as Timeline Updates, Direct Messages, Mention Messages as well as Search Results. - Every Inbound Twitter Channel Adapter is a Polling Consumer which means you have to provide a poller - configuration. However, there is one important thing you must understand about Twitter since its inner-workings are slightly - different than other polling consumers. Twitter defines a concept of Rate Limiting. You can read more about - it here: Rate Limiting. In a nutshell, Rate Limiting + Every Inbound Twitter Channel Adapter is a Polling Consumer which means you have to provide a poller + configuration. However, there is one important thing you must understand about Twitter since its inner-workings are slightly + different than other polling consumers. Twitter defines a concept of Rate Limiting. You can read more about + it here: Rate Limiting. In a nutshell, Rate Limiting is the way Twitter manages how often an application can poll for updates. You should consider this when setting your - poller intervals, but we are also doing a few things to limit excessively aggressive polling within our adapters. + poller intervals, but we are also doing a few things to limit excessively aggressive polling within our adapters. - Another issue that we need to worry about is handling duplicate Tweets. The same adapter (e.g., Search or Timeline Update) - while polling on Twitter may receive the same values more than once. For example if you keep searching on Twitter with the same search - criteria you'll end up with the same set of tweets unless some other new tweet that matches your search criteria was posted - in between your searches. In that situation you'll get all the tweets you had before plus the new one. But what you really + Another issue that we need to worry about is handling duplicate Tweets. The same adapter (e.g., Search or Timeline Update) + while polling on Twitter may receive the same values more than once. For example if you keep searching on Twitter with the same search + criteria you'll end up with the same set of tweets unless some other new tweet that matches your search criteria was posted + in between your searches. In that situation you'll get all the tweets you had before plus the new one. But what you really want is only the new tweet(s). Spring Integration provides an elegant mechanism for handling these situations. - The latest Tweet timestamp will be stored in an instance of the org.springframework.integration.store.MetadataStore which is a + The latest Tweet timestamp will be stored in an instance of the org.springframework.integration.store.MetadataStore which is a strategy interface designed for storing various types of metadata (e.g., last retrieved tweet in this case). That strategy helps components such as these Twitter adapters avoid duplicates. By default, Spring Integration will look for a bean of type org.springframework.integration.store.MetadataStore in the ApplicationContext. - If one is found then it will be used, otherwise it will create a new instance of SimpleMetadataStore + If one is found then it will be used, otherwise it will create a new instance of SimpleMetadataStore which is a simple in-memory implementation that will only persist metadata within the lifecycle of the currently running application context. - That means upon restart you may end up with duplicate entries. If you need to persist metadata between Application Context + That means upon restart you may end up with duplicate entries. If you need to persist metadata between Application Context restarts, you may use the PropertiesPersistingMetadataStore (which is backed by a properties file, and a persister strategy), or you may create your own custom implementation of the MetadataStore interface (e.g., JdbcMetadatStore) and configure it as a bean named 'metadataStore' within the Application Context. - + ]]> The Poller that is configured as part of any Inbound Twitter Adapter (see below) will simply poll from this MetadataStore to determine the latest tweet received. @@ -160,105 +160,105 @@ received. Inbound Message Channel Adapter This adapter allows you to receive updates from everyone you follow. It's essentially the "Timeline Update" adapter. - ]]>
- +
Direct Inbound Message Channel Adapter This adapter allows you to receive Direct Messages that were sent to you from other Twitter users. - ]]>
- +
Mentions Inbound Message Channel Adapter This adapter allows you to receive Twitter Messages that Mention you via @user syntax. - ]]>
- + - As you can see the configuration of all of these adapters is very similar to other inbound adapters with one exception. - Some may need to be injected with the twitter-template. Once received each Twitter Message would be - encapsulated in a Spring Integration Message and sent to the channel specified by the channel attribute. - Currently the Payload type of any Message is org.springframework.integration.twitter.core.Tweet - which is very similar to the object with the same name in Spring Social. As we migrate to Spring Social + As you can see the configuration of all of these adapters is very similar to other inbound adapters with one exception. + Some may need to be injected with the twitter-template. Once received each Twitter Message would be + encapsulated in a Spring Integration Message and sent to the channel specified by the channel attribute. + Currently the Payload type of any Message is org.springframework.integration.twitter.core.Tweet + which is very similar to the object with the same name in Spring Social. As we migrate to Spring Social we'll be depending on their API and some of the artifacts that are currently in use will be obsolete, however we've already made sure that the impact of such migration is minimal by aligning our API with the current state (at the time of writing) of Spring Social. To get the text from the org.springframework.social.twitter.api.Tweet - simply invoke the getText() method. + simply invoke the getText() method.
- +
Twitter Outbound Adapter Twitter outbound channel adapters allow you to send Twitter Messages, or tweets. - The current release of Spring Integration supports sending Status Update Messages and Direct Messages. + The current release of Spring Integration supports sending Status Update Messages and Direct Messages. Twitter outbound channel adapters will take the Message payload and send it as a Twitter message. Currently the only supported payload type is - String, so consider adding a transformer if the payload of the incoming message is not a String. + String, so consider adding a transformer if the payload of the incoming message is not a String. - +
Twitter Outbound Update Channel Adapter - This adapter allows you to send regular status updates by simply sending a Message to the channel - identified by the channel attribute. - channel attribute. + ]]> The only extra configuration that is required for this adapter is the twitter-template reference.
- +
Twitter Outbound Direct Message Channel Adapter - This adapter allows you to send Direct Twitter Messages (i.e., @user) by simply sending a Message to the channel - identified by the channel attribute. - channel attribute. + ]]> The only extra configuration that is required for this adapter is the twitter-template reference. - When it comes to Twitter Direct Messages, you must specify who you are sending the message to - the target userid. + When it comes to Twitter Direct Messages, you must specify who you are sending the message to - the target userid. The Twitter Outbound Direct Message Channel Adapter will look for a target userid in the Message headers under the name twitter_dmTargetUserId which is also identified by the following constant: TwitterHeaders.DM_TARGET_USER_ID. So when creating a Message all you need to do is add a value for that header. @@ -270,20 +270,21 @@ received. The above approach works well if you are creating the Message programmatically. However it's more common to provide the header value within a messaging flow. The value can be provided by an upstream <header-enricher>. - + ]]> It's quite common that the value must be determined dynamically. For those cases you can take advantage of SpEL support within the <header-enricher>. - + ]]>
- Twitter does not allow you to post duplicate Messages. This is a common problem during testing when + Twitter does not allow you to post duplicate Messages. This is a common problem during testing when the same code works the first time but does not work the second time. So, make sure to change the content of the Message each time. Another thing that works well for testing is to append a timestamp to the end of each message. diff --git a/src/reference/docbook/ws.xml b/src/reference/docbook/ws.xml index 68f1fd8530..bed205f37c 100644 --- a/src/reference/docbook/ws.xml +++ b/src/reference/docbook/ws.xml @@ -136,9 +136,9 @@ as per standard Spring Web Services configuration. For URIs with an http: (or https:) scheme, <uri-variable/> substitution is supported: - - - + + + ]]> For other schemes, such as jms:, or if a DestinationProvider diff --git a/src/reference/docbook/xml.xml b/src/reference/docbook/xml.xml index b0bfd2a3ae..ffdad3c1bd 100644 --- a/src/reference/docbook/xml.xml +++ b/src/reference/docbook/xml.xml @@ -110,12 +110,12 @@ Here is an overview of all available configuration parameters of the xpath-expression element: - ]]> ]]> ]]> ]]>]]> diff --git a/src/reference/docbook/xmpp.xml b/src/reference/docbook/xmpp.xml index dd109c0411..ffd6db4221 100644 --- a/src/reference/docbook/xmpp.xml +++ b/src/reference/docbook/xmpp.xml @@ -27,46 +27,44 @@ - Spring integration provides support for XMPP via XMPP adapters which support sending and receiving both XMPP chat messages and + 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 with other adapters, the XMPP adapters come with support for a - convenient namespace-based configuration. + convenient namespace-based configuration. To configure the XMPP namespace, include the following elements in the headers of your XML configuration file: - + - +
- +
XMPP Connection Before using inbound or outbound XMPP adapters to participate in the XMPP network, an actor must establish its XMPP connection. This - connection object could be shared by all XMPP adapters connected to a particular account. Typically this requires - at a minimum - + connection object could be shared by all XMPP adapters connected to a particular account. Typically this requires - at a minimum - user, password, and host. To create a basic XMPP connection, you can utilize the convenience of the namespace. + + ]]> - - ]]> - - - For added convenience you can rely on the default naming convention and omit the id attribute. + For added convenience you can rely on the default naming convention and omit the id attribute. The default name xmppConnection will be used for this connection bean. - If the XMPP Connection goes stale, reconnection attempts will be made with an automatic login as long as the previous connection + If the XMPP Connection goes stale, reconnection attempts will be made with an automatic login as long as the previous connection state was logged (authenticated). We also register a ConnectionListener which will log connection events if the DEBUG logging level is enabled. @@ -84,55 +82,55 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/xmpp java.lang.String if you set the extract-payload attribute's value to 'true' when configuring an adapter. Configuration support for the XMPP Inbound Message Channel Adapter is provided via the inbound-channel-adapter element. - - ]]> - - As you can see amongst the usual attributes this adapter also requires a reference to an XMPP Connection. + + ]]> + + 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 the XMPP inbound adapter is an event driven adapter - and a Lifecycle implementation. + and a Lifecycle implementation. When started it will register a PacketListener that will listen for incoming XMPP Chat Messages. It forwards any received messages to the underlying adapter which will convert them to Spring Integration Messages and send them to the specified channel. It will unregister the PacketListener when it is stopped.
- +
Outbound Message Channel Adapter - + - You may also send chat messages to other users on XMPP using the Outbound Message Channel Adapter. + You may also send chat messages to other users on XMPP using the Outbound Message Channel Adapter. Configuration support for the XMPP Outbound Message Channel Adapter is provided via the outbound-channel-adapter element. - - ]]> - + + ]]> + The adapter expects as its input - at a minimum - a payload of type java.lang.String, and a header value for XmppHeaders.CHAT_TO that specifies to which user the Message should be sent. To create a message you might use the following Java code: - + xmppOutboundMsg = MessageBuilder.withPayload("Hello, XMPP!" ) .setHeader(XmppHeaders.CHAT_TO, "userhandle") - .build();]]> - - Another mechanism of setting the header is by using the XMPP header-enricher support. Here is an example. - + .build();]]> + + Another mechanism of setting the header is by using the XMPP header-enricher support. Here is an example. + -]]> +]]>
- - + +
XMPP Presence @@ -142,52 +140,52 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/xmpp 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. - - + +
Inbound Presence Message Channel Adapter - Spring Integration provides an Inbound Presence Message Channel Adapter which supports receiving Presence - events from other users in the system who happen to be on your Roster. To do this, the adapter "logs in" as a user - on your behalf, registers a RosterListener and forwards received Presence update events as Messages to the channel + Spring Integration provides an Inbound Presence Message Channel Adapter which supports receiving Presence + events from other users in the system who happen to be on your Roster. To do this, the adapter "logs in" as a user + on your behalf, registers a RosterListener and forwards received Presence update events as Messages to the channel identified by the channel attribute. The payload of the Message will be a org.jivesoftware.smack.packet.Presence object (see http://www.igniterealtime.org/builds/smack/docs/3.1.0/javadoc/org/jivesoftware/smack/packet/Presence.html). - Configuration support for the XMPP Inbound Presence Message Channel Adapter is provided via + Configuration support for the XMPP Inbound Presence Message Channel Adapter is provided via the presence-inbound-channel-adapter element. - ]]> - + ]]> + 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 Lifecycle implementation. - It will register a RosterListener when started and will unregister that RosterListener + It is also important to mention that this adapter is an event driven adapter and a Lifecycle implementation. + It will register a RosterListener when started and will unregister that RosterListener when stopped.
- +
Outbound Presence Message Channel Adapter - + Spring Integration also supports sending Presence events to be seen by other users in the network who happen to have you on their Roster. When you send a Message to the Outbound Presence Message Channel Adapter it extracts the payload, which is expected to be of type org.jivesoftware.smack.packet.Presence - (see http://www.igniterealtime.org/builds/smack/docs/3.1.0/javadoc/org/jivesoftware/smack/packet/Presence.html) and sends it to + (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. - Configuration support for the XMPP Outbound Presence Message Channel Adapter is provided via + Configuration support for the XMPP Outbound Presence Message Channel Adapter is provided via the presence-outbound-channel-adapter element. - - ]]> - - It can also be a Polling Consumer (if it receives Messages from a Pollable Channel) in which case you would + + ]]> + + It can also be a Polling Consumer (if it receives Messages from a Pollable Channel) in which case you would need to register a Poller. - - ]]> @@ -197,7 +195,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/xmpp
- If you are relying on the default naming convention for an XMPP Connection bean (described earlier), and you have only one + If you are relying on the default naming convention for an XMPP Connection bean (described earlier), and you have only one XMPP Connection bean configured in your Application Context, you may omit the xmpp-connection attribute. In that case, the bean with the name xmppConnection will be located and injected into the adapter. @@ -205,48 +203,48 @@ xsi:schemaLocation="http://www.springframework.org/schema/integration/xmpp
Appendices - + - Since Spring Integration XMPP support is based on the Smack 3.1 API (http://www.igniterealtime.org/downloads/index.jsp), it is important + Since Spring Integration XMPP support is based on the 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 the XMPP Connection object. - As stated earlier the xmpp-connection namespace support is designed to simplify basic connection configuration and + As stated earlier the xmpp-connection namespace support is designed to simplify basic connection configuration and only supports a few common configuration attributes. However, the org.jivesoftware.smack.ConnectionConfiguration 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 an instance of our XmppConnectionFactoryBean as a regular bean, and inject a - org.jivesoftware.smack.ConnectionConfiguration as a constructor argument to that FactoryBean. Every property + org.jivesoftware.smack.ConnectionConfiguration as a constructor argument to that FactoryBean. Every property you need, can be specified directly on that ConnectionConfiguration instance (a bean definition with the 'p' namespace would work well). This way SSL, or any other attributes, could be set directly. Here's an example: - - - - - - - - - + + + + + + + + + - -]]> + +]]> - Another important aspect of the Smack API is static initializers. For more complex cases (e.g., registering a SASL Mechanism), you may need - to execute certain static initializers. One of those static initializers is SASLAuthentication, which allows - you to register supported SASL mechanisms. For that level of complexity, we would recommend Spring JavaConfig-style of the XMPP Connection - configuration. Then, you can configure the entire component through Java code and execute all other necessary Java code including + Another important aspect of the Smack API is static initializers. For more complex cases (e.g., registering a SASL Mechanism), you may need + to execute certain static initializers. One of those static initializers is SASLAuthentication, which allows + you to register supported SASL mechanisms. For that level of complexity, we would recommend Spring JavaConfig-style of the XMPP Connection + configuration. Then, you can configure the entire component through Java code and execute all other necessary Java code including static initializers at the appropriate time. - +