diff --git a/src/docbkx/samples.xml b/src/docbkx/samples.xml index 504164956d..854e2afa18 100644 --- a/src/docbkx/samples.xml +++ b/src/docbkx/samples.xml @@ -4,445 +4,422 @@ Spring Integration Samples - - Starting with the current release of Spring Integration the samples are distributed as independent - Maven-based projects (http://maven.apache.org/) to minimize the setup time. - Since each project is also an Eclipse-based project, they can be imported as is using the Eclipse Import wizard. - If you prefer another IDE, configuration should be very trivial, since a special Maven profile was setup to download all - of the required dependencies for all samples. Detailed instructions on how to build and run the samples are provided in - the README.txt file located in the samples directory of the main distribution. - - -
- The Cafe Sample - - In this section, we will review a sample application that is included in the Spring Integration - distribution. This sample is inspired by one of the samples featured in Gregor Hohpe's - Ramblings. - - - The domain is that of a Cafe, and the basic flow is depicted in the following diagram: - - - - - - - - - - - - - The Order object may contain multiple OrderItems. Once the order - is placed, a Splitter will break the composite order message into a single message per - drink. Each of these is then processed by a Router that determines whether the drink is hot - or cold (checking the OrderItem object's 'isIced' property). The - Barista prepares each drink, but hot and cold drink preparation are handled by two - distinct methods: 'prepareHotDrink' and 'prepareColdDrink'. The prepared drinks are then sent to the Waiter where - they are aggregated into a Delivery object. - - - 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(); - } -}]]> - 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. - - - - 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. - - - - 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 - CafeDemo 'main' method runs, it will loop 100 times sending a single hot drink and a - single cold drink each time. It actually sends the messages by invoking the 'placeOrder' method on the Cafe - 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 = (Cafe) context.getBean("cafe"); - 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. - - - When you run cafeDemo, you will see that the cold drinks are initially prepared more quickly than the hot drinks. - Because there is an aggregator, the cold drinks are effectively limited by the rate of the hot drink preparation. - 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), - then you will notice that occasionally it throttles the input by forcing the task-scheduler (the caller) to invoke - the operation. - - - In addition to experimenting with the poller's concurrency settings, you can also add the 'transactional' - sub-element and then refer to any PlatformTransactionManager instance within the context. - -
- -
- The XML Messaging Sample - - The xml messaging sample in the org.springframework.integration.samples.xml illustrates how to use - some of the provided components which deal with xml payloads. The sample uses the idea of processing an order for books - represented as xml. - - - First the order is split into a number of messages, each one representing a single order item using - 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 - from the stock checker about order item stock level. This enriched order item message is then used to route the message. In the - case where the order item is in stock the message is routed to the warehouse. The XPath router makes use of a - MapBasedChannelResolver which maps the XPath evaluation result to a channel reference. - - - - - - - - - - - - -]]> - - - Where the order item is not in stock the message is transformed using - xslt into a format suitable for sending to the supplier. - -]]> - -
+
+ Introduction + + Starting with the current release of Spring Integration the samples are no longer included with + Spring Integration distribution. Instead we've switched to a much simpler collaborative model that should promote + better community participation and community contributions. Samples now have a dedicated Git SCM repository and a + dedicated JIRA Issue Tracking system. Sample development will also have its own lifecycle which is not dependent on the + lifecycle of the framework releases although the repository will still be tagged with each major release for compatibility + reasons. + + + The great benefit to the community is that we can now add more samples and make them available to you right away + without waiting for the release to get them out to you. Having its own JIRA that is not tied up to the the actual + framework is also a great benefit. You now have a dedicated place to suggest samples as well as report issues with existing + samples. Or you may want to submit a sample to us as an attachment through the JIRA and if we believe your sample adds value we + would be more then glad to add it to a samples repository properly crediting the author. + +
-
- The OSGi Samples - - This release of Spring Integration includes several samples that are OSGi enabled as well as samples that were - specifically designed to show some of the other benefits of OSGi and Spring Integration when used together. - First lets look at the two familiar examples that are also configured to be valid OSGi bundles. These are - Hello World and Cafe. All you need to do to see these samples work in - an OSGi environment is deploy the generated JAR into such an environment. - - - Use Maven to generate the JAR by executing the 'mvn install' command on either of these projects. This will - generate the JAR file in the target directory. Now you can simply drop that JAR file into the deployment - directory of your OSGi platform. For example, if you are using - SpringSource dm Server, - drop the files into the 'pickup' directory within the dm Server home directory. - - - Prior to deploying and testing Spring Integration samples in the dm Server or any other OSGi server platform, - you must have the Spring Integration and Spring bundles installed on that platform. For example, to install - Spring Integration into SpringSource dm Server, copy all JAR files that are located in the 'dist' directory of - your Spring Integration distribution into the 'repository/bundles/usr' directory of your dm Server instance - (see the - dm Server User Guide - for more detail on how to install bundles). - - - The Spring Integration samples require a few other bundles to be installed. For the 1.0.3 release, the full - list including transitive dependencies is: - - org.apache.commons.codec-1.3.0.jar - org.apache.commons.collections-3.2.0.jar - org.apache.commons.httpclient-3.1.0.jar - org.apache.ws.commons.schema-1.3.2.jar - org.springframework.oxm-1.5.5.A.jar - org.springframework.security-2.0.4.A.jar - org.springframework.ws-1.5.5.A.jar - org.springframework.xml-1.5.5.A.jar - - These are all located within the 'lib' directory of the Spring Integration distribution. So, you can simply - copy those JARs into the dm Server 'repository/bundles/usr' directory as well. - - The Spring Framework bundles (aop, beans, context, etc.) are also included in the 'lib' directory of the - Spring Integration distribution, but they do not need to be installed since they are already part of the - dm Server infrastructure. Also, note that the versions listed above are those included with the Spring - Integration 1.0.3 release. Newer versions of individual JARs may be used as long as they are within the - range specified in the MANIFEST.MF files of those bundles that depend upon them. - - - The bundles listed above are appropriate for a SpringSource dm Server 1.0.x deployment environment - with a Spring Framework 2.5.x foundation. That is the version against which Spring Integration 1.0.3 - has been developed and tested. However, as of the time of the Spring Integration 1.0.3 release, the - Spring Framework 3.0 release candidates are about to be available, and the dm Server 2.0.x milestones - are available. If you want to try running these samples in that environment, then you will need to - replace the Spring Security and Spring Web Services bundles with versions that support Spring 3.0. - The OXM functionality is moving into the Spring Framework itself for the 3.0 release. Otherwise, - Spring Integration 1.0.3 has been superficially tested against the Spring 3.0 snapshots available - at the time of its release. In fact, some internal changes were made in the 1.0.3 release - specifically to support Spring 3.0 (whereas 1.0.2 does not). Spring Integration 2.0 will be built - upon a Spring 3.0 foundation. - - - - To demonstrate some of the benefits of running Spring Integration projects in an OSGi environment (e.g. - modularity, OSGi service dynamics, etc.), we have included a couple new samples that are dedicated to - highlighting those benefits. In the 'samples' directory, you will find the following two projects: - - osgi-inbound (producer bundle) - osgi-outbound (consumer bundle) - - Unlike the other samples in the distribution, these are not Maven enabled. Instead, we have simply configured - them as valid dm Server Bundle projects. That means you can import these projects directly into an STS - workspace using the "Existing Projects into Workspace" option from the Eclipse Import wizard. Then, you can - take advantage of the STS dm Server tools to deploy them into a SpringSource dm Server instance. - - A simple Ant 'build.xml' file has been included within each of these projects as well. The build - files contain a single 'jar' target. Therefore, after these projects have been built within - Eclipse/STS, you can generate the bundle (JAR) directly and deploy it manually. - - - - The structure of these projects is very simple, yet the concepts they showcase are quite powerful. The - 'osgi-inbound' module enables sending a Message to a Publish-Subscribe Channel using a Spring Integration - Gateway proxy. The interesting part, however, is that the Publish-Subscribe Channel is exported as an OSGi - service via the <osgi:service/> element. As a result, any other bundles can be developed, deployed, and - maintained independently yet still subscribe to that channel. - - - The 'osgi-outbound' module is an example of such a subscribing consumer bundle. It uses the corresponding - <osgi:reference/> element to locate the channel exported by the 'osgi-inbound' bundle. It also contains - configuration for a <file:outbound-gateway/> which is a subscriber to that channel and will write the - Message content to a file once it arrives. It then sends a response Message with the name of the file and its - location. - - - To make it easy to run, we've exposed a command-line interface where you can type in the command, the message, - and the file name to execute the demo. This is exposed through the OSGi console. Likewise, the response that - provides the name and location of the resulting file will also be visible within the OSGi console. - - - To run these samples, make sure your OSGi environment is properly configured to host Spring Integration bundles - (as described in the note above). Deploy the producer bundle (osgi-inbound) first, and then deploy the consumer - bundle (osgi-outbound). After you have deployed these bundles, open the OSGi console and type the following - command: - help ]]> - You will see the following amidst the output: - - send text to be written to a file]]> - As you can see, that describes the command that you will be able to use to send messages. If you are interested - in how it is implemented or want to customize message sending logic or even create a new command look at - InboundDemoBundleActivator.java in the consumer bundle. - - When using the SpringSource Tool Suite, you can open the OSGi console by first opening the dm Server - view and then choosing the 'Server Console' tab at the bottom (to open the dm Server view, navigate to - the dm Server instance listed in the 'Servers' view and either double-click or hit F3). Alternatively, - you can open the OSGi console by connecting to port 2401 via telnet (as long as that is enabled, and - for dm Server, it is enabled by default): - telnet localhost 2401 - - - - Now send a message by typing: siSend "Hello World" hello.txt]]> - You will see something similar to the following in the OSGi console: - - - It is not necessary to wrap the message in quotes if it does not contain spaces. - Go ahead and open up the file and verify that the message content was written to it. - - - - Let's assume you wanted to change the directory to which the files are written or make any other change to the - consumer bundle (osgi-outboud). You only need to update the consumer bundle and not the producer bundle. So, go - ahead and change the directory in the 'osgi-outbound.xml' file located within 'src/META-INF/spring' and refresh - the consumer bundle. - - If using STS to deploy to dm Server, the refresh will happen automatically. If replacing bundles manually, - you can issue the command 'refresh n' in the OSGi console (where n would be the ID of the bundle as - displayed at any point after issuing the 'ss' command to see the short status output). - - You will see that the change takes affect immediately. Not only that, you could even start developing and - deploying new bundles that subscribe to the messages produced by the producer bundle the same way as the existing - consumer bundle (osgi-outbound) does. With a publish-subscribe-channel any newly deployed bundles would start - receiving each Message as well. - - If you also want to modify and refresh the producer bundle, be sure to refresh the consumer bundle - afterwards as well. This is necessary because the consumer's subscription must be explicitly re-enabled - after the producer's channel disappears. You could alternatively deploy a relatively static bundle that - defines channels so that producers and consumers can be completely dynamic without affecting each other - at all. In Spring Integration 2.0, we plan to support automatic re-subscription and more through the use - of a Control Bus. - - - - That pretty much wraps up this very simple example. Hopefully it has successfully demonstrated the benefits of - modularity and OSGi service dynamics while working with Spring Integration. Feel free to experiment by following - some of the suggestions mentioned above. For deeper coverage of the applicability of OSGi when used with Spring - Integration, read this blog - by Spring Integration team member Iwein Fuld. - +
+ Where to get Samples + + To monitor samples development and to get more information on the repository you can visit the following + URL: http://git.springsource.org/spring-integration/samples + Since we are using Git SCM we should use the proper terminology as well when it comes to the tasks you need to perform to make + samples available locally on your machine. For more information on Git SCM please visit their + website: http://git-scm.com/ + + + CLONE samples repository. (For those unfamiliar with Git, this is somewhat the equivalent of a checkout.) + + + This is the first step you should go through. You must have Git installed on your machine. There are many GUI-based products + available for many platforms. Simple Google search will let you find them. + To clone samples repository from command line: + mkdir spring-itegration-samples +> cd spring-itegration-samples +> git clone git://git.springsource.org/spring-integration/samples.git]]> + + + That is all you need to do. Now you have cloned the entire samples repository. Since samples repository is a live + repository, you might want to perform periodic updates to get new samples as well as updates to the existing samples. + To get the updates use git PULL command: + git pull]]> + + + Submit samples or sample requests + + + As mentioned earlier, Spring Integration samples have a dedicated JIRA Issue tracking system. + To submit new sample request or to submit the actual sample (as an attachment) please visit our JIRA Issue Tracking system: + https://jira.springframework.org/browse/INTSAMPLES  + +
+
+ Samples structure + + The structure of the samples changed as well. With plans for more samples we realized that some + samples have different goals then others. While they all share the common  goal of showing you how to apply and work with + Spring Integration framework, they also defer in areas where some samples were meant to concentrate on a technical + use case while others on the business use case and some samples are all about showcasing various techniques that + could be applied to address certain scenarios (both technical and business). Categorization of samples will allow us + better organize them based on the problem each sample addresses while giving you a simpler way of finding the right sample + + + Currently there are 4 categories. Within the samples repository each category has its own directory which is named after the + category name: + + + + BASIC (samples/basic) + + + This is a good place to get started. The samples here are technically motivated and demonstrate the bare + minimum with regard to configuration and code, to help you to get started quickly by introducing you to the basic concepts, + API and configuration of Spring Integration as well as Enterprise Integration Patterns (EIP). For example; If your are + looking for an answer on how to implement and wire Service Activator to a Channel + or how to use Messaging Gateway to your message exchange or how to get started with using MAIL or + TCP/UDP modules etc., this would be the right place to find a good sample. The bottom line is this is a good place + to get started. + + + + INTERMEDIATE (samples/intermediate) + + + This category targets developers who are already familiar with Spring Integration framework (past getting started), + but need some more guidance while resolving a more advanced technical problems one might deal with + once switch to a Messaging architecture. + For example; If you are looking for an answer on how to handle errors in various message exchange + scenarios or how to properly configure the Aggregator for the situations where some messages + might not ever arrive for aggregation etc,. and any other issue that goes beyond a basic implementation and configuration + of a particular component and addresses "what else you can do with it" type of problem this + would be the right place to find these type of samples. + + + + ADVANCED (samples/advanced) + + + This category targets develoopers who are very familiar with Spring Integration framework but looking to + extend it to address a specific custom need by using Spring Integration public API. + For example; if you are looking for samples showing you how to implement a custom Channel or + Consumer (event-based or polling-based), or you trying to figure out what is the most appropriate + way to implement custom Bean parser on top of Spring Integration Bean parsers hierarchy when implementing custom name space + for a custom component, this would be the right place to look. + Here you can also find samples that will help you with Adapter development. Spring Integration comes + with an extensive library of adapters to allow you to connect remote systems with Spring Integration messaging framework. + However you might have a need to integrate with system for which the core framework does not provide an adapter. + So you have to implement your own. This category would include samples showing you how to do it. + + + + + APPLICATIONS (samples/applications) + + + This category targets developers and architects who have a good understanding of the Messaging architecture, + EIP and above average understanding of Spring and Spring Integration frameworks and are looking for samples that + address a particular business problem. In other words the emphasis of samples in this category + is business use cases and how it could be solved via Messaging Architecture and Spring Integration + in particular. + For example; If you are interested to see how a Loan Broker or Travel Agent + process could be implemented and automated via Spring Integration this would be the right place to find these types of samples. + + + + + Remember! Spring Integration is a community driven framework, therefore community participation is IMPORTANT. +That includes Samples, so if you can't find what you are looking for let us know. + + +
+ +
+ Samples + + Currently Spring Integration comes with quite a few samples and you can only expect more. + To help you better navigate through them, each sample comes with its own readme.txt file which coveres + sevaral details about the sample (e.g., what EIP patterns it addresses, what problem it is trying to solve, how to run sample etc.). + However, certain samples require a more detailed and some times graphical explanation. In these section you'll + find details on samples that we believe require special attention. + +
+ Loan Broker +
+
+ The Cafe Sample + + In this section, we will review a sample application that is included in the Spring Integration + distribution. This sample is inspired by one of the samples featured in Gregor Hohpe's + Ramblings. + + + The domain is that of a Cafe, and the basic flow is depicted in the following diagram: + + + + + + + + + + + + + The Order object may contain multiple OrderItems. Once the order + is placed, a Splitter will break the composite order message into a single message per + drink. Each of these is then processed by a Router that determines whether the drink is hot + or cold (checking the OrderItem object's 'isIced' property). The + Barista prepares each drink, but hot and cold drink preparation are handled by two + distinct methods: 'prepareHotDrink' and 'prepareColdDrink'. The prepared drinks are then sent to the Waiter where + they are aggregated into a Delivery object. + + + 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(); + } + }]]> + 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. + + + + 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. + + + + 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 + CafeDemo 'main' method runs, it will loop 100 times sending a single hot drink and a + single cold drink each time. It actually sends the messages by invoking the 'placeOrder' method on the Cafe + 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 = (Cafe) context.getBean("cafe"); + 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. + + + When you run cafeDemo, you will see that the cold drinks are initially prepared more quickly than the hot drinks. + Because there is an aggregator, the cold drinks are effectively limited by the rate of the hot drink preparation. + 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), + then you will notice that occasionally it throttles the input by forcing the task-scheduler (the caller) to invoke + the operation. + + + In addition to experimenting with the poller's concurrency settings, you can also add the 'transactional' + sub-element and then refer to any PlatformTransactionManager instance within the context. + +
+ +
+ The XML Messaging Sample + + The xml messaging sample in the org.springframework.integration.samples.xml illustrates how to use + some of the provided components which deal with xml payloads. The sample uses the idea of processing an order for books + represented as xml. + + + First the order is split into a number of messages, each one representing a single order item using + 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 + from the stock checker about order item stock level. This enriched order item message is then used to route the message. In the + case where the order item is in stock the message is routed to the warehouse. The XPath router makes use of a + MapBasedChannelResolver which maps the XPath evaluation result to a channel reference. + + + + + + + + + + + + + ]]> + + + Where the order item is not in stock the message is transformed using + xslt into a format suitable for sending to the supplier. + + ]]> + +
+