Modified: websites/production/camel/content/book-component-appendix.html ============================================================================== --- websites/production/camel/content/book-component-appendix.html (original) +++ websites/production/camel/content/book-component-appendix.html Fri Oct 21 19:19:58 2016 @@ -282,10 +282,8 @@ <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">from(&quot;atom://http://macstrac.blogspot.com/feeds/posts/default&quot;).to(&quot;seda:feeds&quot;); </script> </div> </div><p>In this sample we want to filter only good blogs we like to a SEDA queue. The sample also shows how to setup Camel standalone, not running in any Container or using Spring. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> // This is the CamelContext that is the heart of Camel private CamelContext context; protected CamelContext createCamelContext() throws Exception { // First we register a blog service in our bean registry SimpleRegistry registry = new SimpleRegistry(); registry.put(&quot;blogService&quot;, new BlogService()); // Then we create the camel context with our bean registry context = new DefaultCamelContext(registry); // Then we add all the routes we need using the route builder DSL syntax context.addRoutes(createMyRoutes()); return context; } /** * This is the route builder where we create our routes using the Camel DSL */ protected RouteBuilder createMyRoutes() throws Exception { return new RouteBuilder() { public void configure() throws Exception { // We pool the atom feeds from the source for further processing in the seda queue // we set the delay to 1 second for each pool as this is a unit test also and we can // not wait the default poll interval of 60 seconds. // Using splitEntries=true will during polling only fetch one Atom Entry at any given time. // As the feed.atom file contains 7 entries, using this will require 7 polls to fetch the entire // content. When Camel have reach the end of entries it will refresh the atom feed from URI source // and restart - but as Camel by default uses the UpdatedDateFilter it will only deliver new // blog entries to &quot;seda:feeds&quot;. So only when James Straham updates his blog with a new entry // Camel will create an exchange for the seda:feeds. from(&quot;atom:file:src/test/data/feed.atom?splitEntries=true&amp;consumer.delay=1000&quot;).to(&quot;seda:feeds&quot;); // From the feeds we filter each blot entry by using our blog service class from(&quot;seda:feeds&quot;).filter().method(&quot;blogService&quot;, &quot;isGoodBlog&quot;).to(&quot;seda:goodBlogs&quot;); // And the good blogs is moved to a mock queue as this sample is also used for unit testing // this is one of the strengths in Camel that you can also use the mock endpoint for your // unit tests from(&quot;seda:goodBlogs&quot;).to(&quot;mock:result&quot;); } }; } /** * This is the actual junit test method that does the assertion that our routes is working as expected */ @Test public void testFiltering() throws Exception { // create and start Camel context = createCamelContext(); context.start(); // Get the mock endpoint MockEndpoint mock = context.getEndpoint(&quot;mock:result&quot;, MockEndpoint.class); // There should be at least two good blog entries from the feed mock.expectedMinimumMessageCount(2); // Asserts that the above expectations is true, will throw assertions exception if it failed // Camel will default wait max 20 seconds for the assertions to be true, if the conditions // is true sooner Camel will continue mock.assertIsSatisfied(); // stop Cam el after use context.stop(); } /** * Services for blogs */ public class BlogService { /** * Tests the blogs if its a good blog entry or not */ public boolean isGoodBlog(Exchange exchange) { Entry entry = exchange.getIn().getBody(Entry.class); String title = entry.getTitle(); // We like blogs about Camel boolean good = title.toLowerCase().contains(&quot;camel&quot;); return good; } } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h3 id="BookComponentAppendix-SeeAlso.3">See Also</h3> <ul><li><a shape="rect" href="configuring-camel.html">Configuring Camel</a></li><li><a shape="rect" href="component.html">Component</a></li><li><a shape="rect" href="endpoint.html">Endpoint</a></li><li><a shape="rect" href="getting-started.html">Getting Started</a></li></ul><ul class="alternate"><li><a shape="rect" href="rss.html">RSS</a></li></ul><h2 id="BookComponentAppendix-BeanComponent">Bean Component</h2><p>The <strong>bean:</strong> component binds beans to Camel message exchanges.</p><h3 id="BookComponentAppendix-URIformat.3">URI format</h3><div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> @@ -299,29 +297,21 @@ </p><div class="error"> <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>Once an endpoint has been registered, you can build Camel routes that use it to process exchanges. - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> // lets add simple route camelContext.addRoutes(new RouteBuilder() { public void configure() { from(&quot;direct:hello&quot;).transform().constant(&quot;Good Bye!&quot;); } }); </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>A <strong>bean:</strong> endpoint cannot be defined as the input to the route; i.e. you cannot consume from it, you can only route from some inbound message <a shape="rect" href="endpoint.html">Endpoint</a> to the bean endpoint as output. So consider using a <strong>direct:</strong> or <strong>queue:</strong> endpoint as the input.<p>You can use the <code>createProxy()</code> methods on <a shape="rect" class="external-link" href="http://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/component/bean/ProxyHelper.html">ProxyHelper</a> to create a proxy that will generate BeanExchanges and send them to any endpoint: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> ISay proxy = new ProxyBuilder(camelContext).endpoint(&quot;direct:hello&quot;).build(ISay.class); String rc = proxy.say(); assertEquals(&quot;Good Bye!&quot;, rc); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And the same route using Spring DSL:<div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter">&lt;route&gt; &lt;from uri=&quot;direct:hello&quot;&gt; &lt;to uri=&quot;bean:bye&quot;/&gt; &lt;/route&gt; </script> </div> </div><h3 id="BookComponentAppendix-Beanasendpoint">Bean as endpoint</h3><p>Camel also supports invoking <a shape="rect" href="bean.html">Bean</a> as an Endpoint. In the route below: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;camelContext xmlns=&quot;http://camel.apache.org/schema/spring&quot;&gt; &lt;route&gt; &lt;from uri=&quot;direct:start&quot;/&gt; &lt;to uri=&quot;myBean&quot;/&gt; &lt;to uri=&quot;mock:results&quot;/&gt; &lt;/route&gt; &lt;/camelContext&gt; &lt;bean id=&quot;myBean&quot; class=&quot;org.apache.camel.spring.bind.ExampleBean&quot;/&gt; </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>What happens is that when the exchange is routed to the <code>myBean</code> Camel will use the <a shape="rect" href="bean-binding.html">Bean Binding</a> to invoke the bean.<br clear="none"> The source for the bean is just a plain POJO: - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> public class ExampleBean { public String sayHello(String name) { return &quot;Hello &quot; + name + &quot;!&quot;; } } </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>Camel will use <a shape="rect" href="bean-binding.html">Bean Binding</a> to invoke the <code>sayHello</code> method, by converting the Exchange's In body to the <code>String</code> type and storing the output of the method on the Exchange Out body.<h3 id="BookComponentAppendix-JavaDSLbeansyntax">Java DSL bean syntax</h3><p>Java DSL comes with syntactic sugar for the <a shape="rect" href="bean.html">Bean</a> component. Instead of specifying the bean explicitly as the endpoint (i.e. <code>to("bean:beanName")</code>) you can use the following syntax:</p><div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">// Send message to the bean endpoint // and invoke method resolved using Bean Binding. from(&quot;direct:start&quot;).beanRef(&quot;beanName&quot;); // Send message to the bean endpoint // and invoke given method. from(&quot;direct:start&quot;).beanRef(&quot;beanName&quot;, &quot;methodName&quot;); </script> @@ -527,85 +517,53 @@ cometds://localhost:8443/service/mychann <table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Name</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Type</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Default</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>algorithm</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>String</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>SHA1WithDSA</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>The name of the JCE Signature algorithm that will be used.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>alias</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>String</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>An alias name that will be used to select a key from the keystore.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>bufferSize</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>Integer</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>2048</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>the size of the buffer used in the signature process.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>certificate</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>Certificate</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>A Certificate used to verify the signature of the exchange's payload. Either this or a Public Key is required.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>keystore</code></p></td><td colspan="1" rowspan="1" class="confluenceT d"><p><code>KeyStore</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>A reference to a JCE Keystore that stores keys and certificates used to sign and verify.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd">keyStoreParameters <strong>Camel 2.14.1</strong></td><td colspan="1" rowspan="1" class="confluenceTd">KeyStoreParameters</td><td colspan="1" rowspan="1" class="confluenceTd">null</td><td colspan="1" rowspan="1" class="confluenceTd">A reference to a Camel KeyStoreParameters Object which wraps a Java KeyStore Object</td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>provider</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>String</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>The name of the JCE Security Provider that should be us ed.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>privateKey</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>PrivateKey</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>The private key used to sign the exchange's payload.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>publicKey</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>PublicKey</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>The public key used to verify the signature of the exchange's payload.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>secureRandom</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>secureRandom</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>A reference to a <code>SecureRandom</code> object that will be used to initialize the Signature service.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>password</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>char[]</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>null</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>The password to access the private key from the keystore</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p><code>clearHeaders</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>String</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><code>true</code></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Remove camel crypto headers from Message after a verify operation (value can be <code>"true"</code>/<code>"false"</code>).</p></td></tr ></tbody></table> </div> </div><h3 id="BookComponentAppendix-Using.2">Using</h3><h4 id="BookComponentAppendix-1)Rawkeys">1) Raw keys</h4><p>The most basic way to way to sign and verify an exchange is with a KeyPair as follows. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:keypair&quot;).to(&quot;crypto:sign:basic?privateKey=#myPrivateKey&quot;, &quot;crypto:verify:basic?publicKey=#myPublicKey&quot;, &quot;mock:result&quot;); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>The same can be achieved with the <a shape="rect" href="spring-xml-extensions.html">Spring XML Extensions</a> using references to keys - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:keypair&quot;/&gt; &lt;to uri=&quot;crypto:sign:basic?privateKey=#myPrivateKey&quot; /&gt; &lt;to uri=&quot;crypto:verify:basic?publicKey=#myPublicKey&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h4 id="BookComponentAppendix-2)KeyStoresandAliases.">2) KeyStores and Aliases.</h4><p>The JCE provides a very versatile keystore concept for housing pairs of private keys and certificates, keeping them encrypted and password protected. They can be retrieved by applying an alias to the retrieval APIs. There are a number of ways to get keys and Certificates into a keystore, most often this is done with the external 'keytool' application. <a shape="rect" class="external-link" href="http://www.exampledepot.com/egs/java.security.cert/CreateCert.html" rel="nofollow">This</a> is a good example of using keytool to create a KeyStore with a self signed Cert and Private key.</p><p>The examples use a Keystore with a key and cert aliased by 'bob'. The password for the keystore and the key is 'letmein'</p><p>The following shows how to use a Keystore via the Fluent builders, it also shows how to load and initialize the keystore. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:keystore&quot;).to(&quot;crypto:sign:keystore?keystore=#keystore&amp;alias=bob&amp;password=letmein&quot;, &quot;crypto:verify:keystore?keystore=#keystore&amp;alias=bob&quot;, &quot;mock:result&quot;); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>Again in Spring a ref is used to lookup an actual keystore instance. - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:keystore&quot;/&gt; &lt;to uri=&quot;crypto:sign:keystore?keystore=#keystore&amp;amp;alias=bob&amp;amp;password=letmein&quot; /&gt; &lt;to uri=&quot;crypto:verify:keystore?keystore=#keystore&amp;amp;alias=bob&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h4 id="BookComponentAppendix-3)ChangingJCEProviderandAlgorithm">3) Changing JCE Provider and Algorithm</h4><p>Changing the Signature algorithm or the Security provider is a simple matter of specifying their names. You will need to also use Keys that are compatible with the algorithm you choose. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> keyPair = getKeyPair(&quot;RSA&quot;); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); // we can set the keys explicitly on the endpoint instances. context.getEndpoint(&quot;crypto:sign:rsa?algorithm=MD5withRSA&quot;, DigitalSignatureEndpoint.class).setPrivateKey(privateKey); context.getEndpoint(&quot;crypto:verify:rsa?algorithm=MD5withRSA&quot;, DigitalSignatureEndpoint.class).setPublicKey(publicKey); from(&quot;direct:algorithm&quot;).to(&quot;crypto:sign:rsa?algorithm=MD5withRSA&quot;, &quot;crypto:verify:rsa?algorithm=MD5withRSA&quot;, &quot;mock:result&quot;); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div> - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:provider&quot;).to(&quot;crypto:sign:provider?privateKey=#myPrivateKey&amp;provider=SUN&quot;, &quot;crypto:verify:provider?publicKey=#myPublicKey&amp;provider=SUN&quot;, &quot;mock:result&quot;); </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>or - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:algorithm&quot;/&gt; &lt;to uri=&quot;crypto:sign:rsa?algorithm=MD5withRSA&amp;amp;privateKey=#rsaPrivateKey&quot; /&gt; &lt;to uri=&quot;crypto:verify:rsa?algorithm=MD5withRSA&amp;amp;publicKey=#rsaPublicKey&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div> - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:provider&quot;/&gt; &lt;to uri=&quot;crypto:sign:provider?privateKey=#myPrivateKey&amp;amp;provider=SUN&quot; /&gt; &lt;to uri=&quot;crypto:verify:provider?publicKey=#myPublicKey&amp;amp;provider=SUN&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h4 id="BookComponentAppendix-4)ChangingtheSignatureMessageHeader">4) Changing the Signature Message Header</h4><p>It may be desirable to change the message header used to store the signature. A different header name can be specified in the route definition as follows - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:signature-header&quot;).to(&quot;crypto:sign:another?privateKey=#myPrivateKey&amp;signatureHeader=AnotherDigitalSignature&quot;, &quot;crypto:verify:another?publicKey=#myPublicKey&amp;signatureHeader=AnotherDigitalSignature&quot;, &quot;mock:result&quot;); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>or - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:signature-header&quot;/&gt; &lt;to uri=&quot;crypto:sign:another?privateKey=#myPrivateKey&amp;amp;signatureHeaderName=AnotherDigitalSignature&quot; /&gt; &lt;to uri=&quot;crypto:verify:another?publicKey=#myPublicKey&amp;amp;signatureHeaderName=AnotherDigitalSignature&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h4 id="BookComponentAppendix-5)Changingthebuffersize">5) Changing the buffersize</h4><p>In case you need to update the size of the buffer... - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:buffersize&quot;).to(&quot;crypto:sign:buffer?privateKey=#myPrivateKey&amp;buffersize=1024&quot;, &quot;crypto:verify:buffer?publicKey=#myPublicKey&amp;buffersize=1024&quot;, &quot;mock:result&quot;); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>or - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:buffersize&quot; /&gt; &lt;to uri=&quot;crypto:sign:buffer?privateKey=#myPrivateKey&amp;amp;bufferSize=1024&quot; /&gt; &lt;to uri=&quot;crypto:verify:buffer?publicKey=#myPublicKey&amp;amp;bufferSize=1024&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h4 id="BookComponentAppendix-6)SupplyingKeysdynamically.">6) Supplying Keys dynamically.</h4><p>When using a Recipient list or similar EIP the recipient of an exchange can vary dynamically. Using the same key across all recipients may be neither feasible nor desirable. It would be useful to be able to specify signature keys dynamically on a per-exchange basis. The exchange could then be dynamically enriched with the key of its target recipient prior to signing. To facilitate this the signature mechanisms allow for keys to be supplied dynamically via the message headers below</p><ul><li><code>Exchange.SIGNATURE_PRIVATE_KEY</code>, <code>"CamelSignaturePrivateKey"</code></li><li><code>Exchange.SIGNATURE_PUBLIC_KEY_OR_CERT</code>, <code>"CamelSignaturePublicKeyOrCert"</code></li></ul><p> - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:headerkey-sign&quot;).to(&quot;crypto:sign:alias&quot;); from(&quot;direct:headerkey-verify&quot;).to(&quot;crypto:verify:alias&quot;, &quot;mock:result&quot;); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>or - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:headerkey-sign&quot;/&gt; &lt;to uri=&quot;crypto:sign:headerkey&quot; /&gt; &lt;/route&gt; &lt;route&gt; &lt;from uri=&quot;direct:headerkey-verify&quot;/&gt; &lt;to uri=&quot;crypto:verify:headerkey&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>Even better would be to dynamically supply a keystore alias. Again the alias can be supplied in a message header<ul><li><code>Exchange.KEYSTORE_ALIAS</code>, <code>"CamelSignatureKeyStoreAlias"</code></li></ul><p> - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:alias-sign&quot;).to(&quot;crypto:sign:alias?keystore=#keystore&quot;); from(&quot;direct:alias-verify&quot;).to(&quot;crypto:verify:alias?keystore=#keystore&quot;, &quot;mock:result&quot;); </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>or - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;direct:alias-sign&quot;/&gt; &lt;to uri=&quot;crypto:sign:alias?keystore=#keystore&quot; /&gt; &lt;/route&gt; &lt;route&gt; &lt;from uri=&quot;direct:alias-verify&quot;/&gt; &lt;to uri=&quot;crypto:verify:alias?keystore=#keystore&quot; /&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>The header would be set as follows<div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">Exchange unsigned = getMandatoryEndpoint(&quot;direct:alias-sign&quot;).createExchange(); unsigned.getIn().setBody(payload); unsigned.getIn().setHeader(DigitalSignatureConstants.KEYSTORE_ALIAS, &quot;bob&quot;); unsigned.getIn().setHeader(DigitalSignatureConstants.KEYSTORE_PASSWORD, &quot;letmein&quot;.toCharArray()); template.send(&quot;direct:alias-sign&quot;, unsigned); Exchange signed = getMandatoryEndpoint(&quot;direct:alias-sign&quot;).createExchange(); signed.getIn().copyFrom(unsigned.getOut()); signed.getIn().setHeader(KEYSTORE_ALIAS, &quot;bob&quot;); template.send(&quot;direct:alias-verify&quot;, signed); </script> @@ -621,8 +579,8 @@ cometds://localhost:8443/service/mychann <div class="confluence-information-macro-body"> <p>When using CXF in streaming modes (see DataFormat option), then also read about <a shape="rect" href="stream-caching.html">Stream caching</a>.</p> </div> -</div><p>The <strong>cxf:</strong> component provides integration with <a shape="rect" href="http://cxf.apache.org">Apache CXF</a> for connecting to JAX-WS services hosted in CXF.</p><p><style type="text/css">/**/ div.rbtoc1477048754138 {padding: 0px;} div.rbtoc1477048754138 ul {list-style: disc;margin-left: 0px;} div.rbtoc1477048754138 li {margin-left: 0px;padding-left: 0px;} /**/</style> - </p><div class="toc-macro rbtoc1477048754138"> +</div><p>The <strong>cxf:</strong> component provides integration with <a shape="rect" href="http://cxf.apache.org">Apache CXF</a> for connecting to JAX-WS services hosted in CXF.</p><p><style type="text/css">/**/ div.rbtoc1477077490386 {padding: 0px;} div.rbtoc1477077490386 ul {list-style: disc;margin-left: 0px;} div.rbtoc1477077490386 li {margin-left: 0px;padding-left: 0px;} /**/</style> + </p><div class="toc-macro rbtoc1477077490386"> <ul class="toc-indentation"><li><a shape="rect" href="#BookComponentAppendix-CXFComponent">CXF Component</a> <ul class="toc-indentation"><li><a shape="rect" href="#BookComponentAppendix-URIformat">URI format</a></li><li><a shape="rect" href="#BookComponentAppendix-Options">Options</a> <ul class="toc-indentation"><li><a shape="rect" href="#BookComponentAppendix-Thedescriptionsofthedataformats">The descriptions of the dataformats</a> @@ -833,14 +791,10 @@ cometds://localhost:8443/service/mychann <div class="confluence-information-macro-body"> <p>Currently, the CXF Bean component has (only) been tested with the <a shape="rect" href="jetty.html">Jetty component</a>. It understands headers from <a shape="rect" href="jetty.html">Jetty component</a> without requiring conversion.</p> </div> -</div><h3 id="BookComponentAppendix-AWorkingSample">A Working Sample</h3><p>This sample shows how to create a route that starts an embedded Jetty HTTP server. The route sends requests to a CXF Bean and invokes a JAX-RS annotated service.</p><p>First, create a route as follows: The <code>from</code> endpoint is a Jetty HTTP endpoint that is listening on port 9000. Notice that the <code>matchOnUriPrefix</code> option must be set to <code>true</code> because the RESTful request URI will not exactly match the endpoint's URI http:­//localhost:9000.</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from ref=&quot;ep1&quot; /&gt; &lt;to uri=&quot;cxfbean:customerServiceBean&quot; /&gt; &lt;to uri=&quot;mock:endpointA&quot; /&gt; &lt;/route&gt; </script> - </div> -</div><p>The <code>to</code> endpoint is a CXF Bean with bean name <code>customerServiceBean</code>. The name will be looked up from the registry. Next, we make sure our service bean is available in Spring registry. We create a bean definition in the Spring configuration. In this example, we create a List of service beans (of one element). We could have created just a single bean without a List.</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;util:list id=&quot;customerServiceBean&quot;&gt; &lt;bean class=&quot;org.apache.camel.component.cxf.jaxrs.testbean.CustomerService&quot; /&gt; &lt;/util:list&gt; &lt;bean class=&quot;org.apache.camel.wsdl_first.PersonImpl&quot; id=&quot;jaxwsBean&quot; /&gt; </script> - </div> +</div><h3 id="BookComponentAppendix-AWorkingSample">A Working Sample</h3><p>This sample shows how to create a route that starts an embedded Jetty HTTP server. The route sends requests to a CXF Bean and invokes a JAX-RS annotated service.</p><p>First, create a route as follows: The <code>from</code> endpoint is a Jetty HTTP endpoint that is listening on port 9000. Notice that the <code>matchOnUriPrefix</code> option must be set to <code>true</code> because the RESTful request URI will not exactly match the endpoint's URI http:­//localhost:9000.</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> +</div><p>The <code>to</code> endpoint is a CXF Bean with bean name <code>customerServiceBean</code>. The name will be looked up from the registry. Next, we make sure our service bean is available in Spring registry. We create a bean definition in the Spring configuration. In this example, we create a List of service beans (of one element). We could have created just a single bean without a List.</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><p>That's it. Once the route is started, the web service is ready for business. A HTTP client can make a request and receive response.</p><h2 id="BookComponentAppendix-CXFRSComponent">CXFRS Component</h2><div class="confluence-information-macro confluence-information-macro-note"> <span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span> <div class="confluence-information-macro-body"> @@ -1043,42 +997,24 @@ cometds://localhost:8443/service/mychann <div class="table-wrap"> <table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Name </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Type </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Default </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Description </p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>method</code> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>String</code> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>null</code> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> The method name that bean will be invoked. If not provided, Camel will try to pick the method itself. In case of ambiguity an exception is thrown. See <a shape="rect" href="bean-binding.html">Bean Binding</a> for more details. </p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>multiParameterArray</code> </p></td><td colspan="1" rowspan="1" c lass="confluenceTd"><p> <code>boolean</code> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> <code>false</code> </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> How to treat the parameters which are passed from the message body; if it is <code>true</code>, the In message body should be an array of parameters. </p></td></tr></tbody></table> </div> -</div><p>You can append query options to the URI in the following format, <code>?option=value&option=value&...</code></p><p>The <a shape="rect" href="ejb.html">EJB</a> component extends the <a shape="rect" href="bean.html">Bean</a> component in which most of the details from the <a shape="rect" href="bean.html">Bean</a> component applies to this component as well.</p><h3 id="BookComponentAppendix-BeanBinding.1">Bean Binding</h3><p>How bean methods to be invoked are chosen (if they are not specified explicitly through the <strong>method</strong> parameter) and how parameter values are constructed from the <a shape="rect" href="message.html">Message</a> are all defined by the <a shape="rect" href="bean-binding.html">Bean Binding</a> mechanism which is used throughout all of the various <a shape="rect" href="bean-integration.html">Bean Integration</a> mechanisms in Camel.</p><h3 id="BookComponentAppendix-Examples.2">Examples</h3><p>In the following examples we use the Greater E JB which is defined as follows:</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"> - <b>GreaterLocal.java</b> - </div> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> public interface GreaterLocal { String hello(String name); String bye(String name); } </script> - </div> -</div><p>And the implementation</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"> - <b>GreaterImpl.java</b> - </div> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> @Stateless public class GreaterImpl implements GreaterLocal { public String hello(String name) { return &quot;Hello &quot; + name; } public String bye(String name) { return &quot;Bye &quot; + name; } } </script> - </div> -</div><h4 id="BookComponentAppendix-UsingJavaDSL">Using Java DSL</h4><p>In this example we want to invoke the <code>hello</code> method on the EJB. Since this example is based on an unit test using Apache OpenEJB we have to set a <code>JndiContext</code> on the <a shape="rect" href="ejb.html">EJB</a> component with the OpenEJB settings.</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> @Override protected CamelContext createCamelContext() throws Exception { CamelContext answer = new DefaultCamelContext(); // enlist EJB component using the JndiContext EjbComponent ejb = answer.getComponent(&quot;ejb&quot;, EjbComponent.class); ejb.setContext(createEjbContext()); return answer; } private static Context createEjbContext() throws NamingException { // here we need to define our context factory to use OpenEJB for our testing Properties properties = new Properties(); properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, &quot;org.apache.openejb.client.LocalInitialContextFactory&quot;); return new InitialContext(properties); } </script> - </div> -</div><p>Then we are ready to use the EJB in the Camel route:</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> from(&quot;direct:start&quot;) // invoke the greeter EJB using the local interface and invoke the hello method .to(&quot;ejb:GreaterImplLocal?method=hello&quot;) .to(&quot;mock:result&quot;); </script> - </div> +</div><p>You can append query options to the URI in the following format, <code>?option=value&option=value&...</code></p><p>The <a shape="rect" href="ejb.html">EJB</a> component extends the <a shape="rect" href="bean.html">Bean</a> component in which most of the details from the <a shape="rect" href="bean.html">Bean</a> component applies to this component as well.</p><h3 id="BookComponentAppendix-BeanBinding.1">Bean Binding</h3><p>How bean methods to be invoked are chosen (if they are not specified explicitly through the <strong>method</strong> parameter) and how parameter values are constructed from the <a shape="rect" href="message.html">Message</a> are all defined by the <a shape="rect" href="bean-binding.html">Bean Binding</a> mechanism which is used throughout all of the various <a shape="rect" href="bean-integration.html">Bean Integration</a> mechanisms in Camel.</p><h3 id="BookComponentAppendix-Examples.2">Examples</h3><p>In the following examples we use the Greater E JB which is defined as follows:</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> +</div><p>And the implementation</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> +</div><h4 id="BookComponentAppendix-UsingJavaDSL">Using Java DSL</h4><p>In this example we want to invoke the <code>hello</code> method on the EJB. Since this example is based on an unit test using Apache OpenEJB we have to set a <code>JndiContext</code> on the <a shape="rect" href="ejb.html">EJB</a> component with the OpenEJB settings.</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> +</div><p>Then we are ready to use the EJB in the Camel route:</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><div class="confluence-information-macro confluence-information-macro-tip"> <p class="title">In a real application server</p> <span class="aui-icon aui-icon-small aui-iconfont-approve confluence-information-macro-icon"></span> <div class="confluence-information-macro-body"> <p>In a real application server you most likely do not have to setup a <code>JndiContext</code> on the <a shape="rect" href="ejb.html">EJB</a> component as it will create a default <code>JndiContext</code> on the same JVM as the application server, which usually allows it to access the JNDI registry and lookup the <a shape="rect" href="ejb.html">EJB</a>s.<br clear="none"> However if you need to access a application server on a remote JVM or the likes, you have to prepare the properties beforehand.</p> </div> -</div><h4 id="BookComponentAppendix-UsingSpringXML">Using Spring XML</h4><p>And this is the same example using Spring XML instead:</p><p>Again since this is based on an unit test we need to setup the <a shape="rect" href="ejb.html">EJB</a> component:</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;!-- setup Camel EJB component --&gt; &lt;bean id=&quot;ejb&quot; class=&quot;org.apache.camel.component.ejb.EjbComponent&quot;&gt; &lt;property name=&quot;properties&quot; ref=&quot;jndiProperties&quot;/&gt; &lt;/bean&gt; &lt;!-- use OpenEJB context factory --&gt; &lt;p:properties id=&quot;jndiProperties&quot;&gt; &lt;prop key=&quot;java.naming.factory.initial&quot;&gt;org.apache.openejb.client.LocalInitialContextFactory&lt;/prop&gt; &lt;/p:properties&gt; </script> - </div> -</div><p>Before we are ready to use <a shape="rect" href="ejb.html">EJB</a> in the Camel routes:</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;camelContext xmlns=&quot;http://camel.apache.org/schema/spring&quot;&gt; &lt;route&gt; &lt;from uri=&quot;direct:start&quot;/&gt; &lt;to uri=&quot;ejb:GreaterImplLocal?method=hello&quot;/&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; &lt;/camelContext&gt; </script> - </div> +</div><h4 id="BookComponentAppendix-UsingSpringXML">Using Spring XML</h4><p>And this is the same example using Spring XML instead:</p><p>Again since this is based on an unit test we need to setup the <a shape="rect" href="ejb.html">EJB</a> component:</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> +</div><p>Before we are ready to use <a shape="rect" href="ejb.html">EJB</a> in the Camel routes:</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h3 id="BookComponentAppendix-SeeAlso.14">See Also</h3><ul><li><a shape="rect" href="configuring-camel.html">Configuring Camel</a></li><li><a shape="rect" href="component.html">Component</a></li><li><a shape="rect" href="endpoint.html">Endpoint</a></li><li><a shape="rect" href="getting-started.html">Getting Started</a></li></ul><ul><li><a shape="rect" href="bean.html">Bean</a></li><li><a shape="rect" href="bean-binding.html">Bean Binding</a></li><li><a shape="rect" href="bean-integration.html">Bean Integration</a></li></ul><h2 id="BookComponentAppendix-Esper">Esper</h2><p>The Esper component supports the <a shape="rect" class="external-link" href="http://esper.codehaus.org" rel="nofollow">Esper Library</a> for Event Stream Processing. The <strong>camel-esper</strong> library is provided by the <a shape="rect" class="external-link" href="http://code.google.com/p/camel-extra/" rel="nofollow">Camel Extra</a> project which hosts all *GPL related components for Camel.</p><h3 id="Bo okComponentAppendix-URIformat.18">URI format</h3><div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">esper:name[?options] </script> @@ -1292,10 +1228,8 @@ cometds://localhost:8443/service/mychann <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">from(&quot;file://inputdir/&quot;).process(new Processor() { public void process(Exchange exchange) throws Exception { Object body = exchange.getIn().getBody(); // do some business logic with the input body } }); </script> </div> </div><p>The body will be a <strong><code>File</code></strong> object that points to the file that was just dropped into the <strong><code>inputdir</code></strong> directory.</p><h4 id="BookComponentAppendix-Writingtofiles">Writing to files</h4><p>Camel is of course also able to write files, i.e. produce files. In the sample below we receive some reports on the SEDA queue that we process before they are being written to a directory. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> public void testToFile() throws Exception { MockEndpoint mock = getMockEndpoint(&quot;mock:result&quot;); mock.expectedMessageCount(1); mock.expectedFileExists(&quot;target/test-reports/report.txt&quot;); template.sendBody(&quot;direct:reports&quot;, &quot;This is a great report&quot;); assertMockEndpointsSatisfied(); } protected JndiRegistry createRegistry() throws Exception { // bind our processor in the registry with the given id JndiRegistry reg = super.createRegistry(); reg.bind(&quot;processReport&quot;, new ProcessReport()); return reg; } protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { // the reports from the seda queue is processed by our processor // before they are written to files in the target/reports directory from(&quot;direct:reports&quot;).process(& amp;quot;processReport&quot;).to(&quot;file://target/test-reports&quot;, &quot;mock:result&quot;); } }; } private static class ProcessReport implements Processor { public void process(Exchange exchange) throws Exception { String body = exchange.getIn().getBody(String.class); // do some business logic here // set the output to the file exchange.getOut().setBody(body); // set the output filename using java code logic, notice that this is done by setting // a special header property of the out exchange exchange.getOut().setHeader(Exchange.FILE_NAME, &quot;report.txt&quot;); } } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h4 id="BookComponentAppendix-WritetosubdirectoryusingExchange.FILE_NAME">Write to subdirectory using <code>Exchange.FILE_NAME</code></h4><p>Using a single route, it is possible to write a file to any number of subdirectories. If you have a route setup as such:</p><div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;bean:myBean&quot;/&gt; &lt;to uri=&quot;file:/rootDirectory&quot;/&gt; &lt;/route&gt; </script> @@ -1329,29 +1263,21 @@ cometds://localhost:8443/service/mychann <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">DEBUG FileConsumer is idempotent and the file has been consumed before. Will skip this file: target\idempotent\report.txt </script> </div> </div><h4 id="BookComponentAppendix-Usingafilebasedidempotentrepository">Using a file based idempotent repository</h4><p>In this section we will use the file based idempotent repository <strong><code>org.apache.camel.processor.idempotent.FileIdempotentRepository</code></strong> instead of the in-memory based that is used as default.<br clear="none"> This repository uses a 1st level cache to avoid reading the file repository. It will only use the file repository to store the content of the 1st level cache. Thereby the repository can survive server restarts. It will load the content of the file into the 1st level cache upon startup. The file structure is very simple as it stores the key in separate lines in the file. By default, the file store has a size limit of 1mb. When the file grows larger Camel will truncate the file store, rebuilding the content by flushing the 1st level cache into a fresh empty file.</p><p>We configure our repository using Spring XML creating our file idempote nt repository and define our file consumer to use our repository with the <strong><code>idempotentRepository</code></strong> using <code>#</code> sign to indicate <a shape="rect" href="registry.html">Registry</a> lookup: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;!-- this is our file based idempotent store configured to use the .filestore.dat as file --&gt; &lt;bean id=&quot;fileStore&quot; class=&quot;org.apache.camel.processor.idempotent.FileIdempotentRepository&quot;&gt; &lt;!-- the filename for the store --&gt; &lt;property name=&quot;fileStore&quot; value=&quot;target/fileidempotent/.filestore.dat&quot;/&gt; &lt;!-- the max filesize in bytes for the file. Camel will trunk and flush the cache if the file gets bigger --&gt; &lt;property name=&quot;maxFileStoreSize&quot; value=&quot;512000&quot;/&gt; &lt;!-- the number of elements in our store --&gt; &lt;property name=&quot;cacheSize&quot; value=&quot;250&quot;/&gt; &lt;/bean&gt; &lt;camelContext xmlns=&quot;http://camel.apache.org/schema/spring&quot;& ;gt; &lt;route&gt; &lt;from uri=&quot;file://target/fileidempotent/?idempotent=true&amp;amp;idempotentRepository=#fileStore&amp;amp;move=done/${file:name}&quot;/&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; &lt;/camelContext&gt; </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h4 id="BookComponentAppendix-UsingaJPAbasedidempotentrepository">Using a JPA based idempotent repository</h4><p>In this section we will use the JPA based idempotent repository instead of the in-memory based that is used as default.</p><p>First we need a persistence-unit in <strong><code>META-INF/persistence.xml</code> where we need to use the class <code>org.apache.camel.processor.idempotent.jpa.MessageProcessed</code></strong> as model. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;persistence-unit name=&quot;idempotentDb&quot; transaction-type=&quot;RESOURCE_LOCAL&quot;&gt; &lt;class&gt;org.apache.camel.processor.idempotent.jpa.MessageProcessed&lt;/class&gt; &lt;properties&gt; &lt;property name=&quot;openjpa.ConnectionURL&quot; value=&quot;jdbc:derby:target/idempotentTest;create=true&quot;/&gt; &lt;property name=&quot;openjpa.ConnectionDriverName&quot; value=&quot;org.apache.derby.jdbc.EmbeddedDriver&quot;/&gt; &lt;property name=&quot;openjpa.jdbc.SynchronizeMappings&quot; value=&quot;buildSchema&quot;/&gt; &lt;property name=&quot;openjpa.Log&quot; value=&quot;DefaultLevel=WARN, Tool=INFO&quot;/&gt; &lt;property name=&quot;openjpa.Multithreaded&quot; value=&quot;true&quot;/&gt; &lt;/properties&gt; &lt;/persistence-unit&gt; </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>Next, we can create our JPA idempotent repository in the spring XML file as well: - <div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;!-- we define our jpa based idempotent repository we want to use in the file consumer --&gt; &lt;bean id=&quot;jpaStore&quot; class=&quot;org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository&quot;&gt; &lt;!-- Here we refer to the entityManagerFactory --&gt; &lt;constructor-arg index=&quot;0&quot; ref=&quot;entityManagerFactory&quot;/&gt; &lt;!-- This 2nd parameter is the name (= a category name). You can have different repositories with different names --&gt; &lt;constructor-arg index=&quot;1&quot; value=&quot;FileConsumer&quot;/&gt; &lt;/bean&gt; </script> - </div> + <div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And yes then we just need to refer to the <strong>jpaStore</strong> bean in the file consumer endpoint using the <strong><code>idempotentRepository</code></strong> using the <code>#</code> syntax option:<div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;file://inbox?idempotent=true&amp;amp;idempotentRepository=#jpaStore&quot;/&gt; &lt;to uri=&quot;bean:processInbox&quot;/&gt; &lt;/route&gt; </script> </div> </div><h3 id="BookComponentAppendix-Filterusingorg.apache.camel.component.file.GenericFileFilter">Filter using <code>org.apache.camel.component.file.GenericFileFilter</code></h3><p>Camel supports pluggable filtering strategies. You can then configure the endpoint with such a filter to skip certain files being processed.</p><p>In the sample we have built our own filter that skips files starting with <strong><code>skip</code></strong> in the filename: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> public class MyFileFilter&lt;T&gt; implements GenericFileFilter&lt;T&gt; { public boolean accept(GenericFile&lt;T&gt; file) { // we want all directories if (file.isDirectory()) { return true; } // we dont accept any files starting with skip in the name return !file.getFileName().startsWith(&quot;skip&quot;); } } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And then we can configure our route using the <strong>filter</strong> attribute to reference our filter (using <code>#</code> notation) that we have defined in the spring XML file:<div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;!-- define our filter as a plain spring bean --&gt; &lt;bean id=&quot;myFilter&quot; class=&quot;com.mycompany.MyFileFilter&quot;/&gt; &lt;route&gt; &lt;from uri=&quot;file://inbox?filter=#myFilter&quot;/&gt; &lt;to uri=&quot;bean:processInbox&quot;/&gt; &lt;/route&gt; </script> @@ -1363,15 +1289,11 @@ cometds://localhost:8443/service/mychann <p>There are now <strong><code>antInclude</code></strong> and <strong><code>antExclude</code></strong> options to make it easy to specify ANT style include/exclude without having to define the filter. See the URI options above for more information.</p> </div> </div><p>The ANT path matcher is shipped out-of-the-box in the <strong>camel-spring</strong> jar. So you need to depend on <strong>camel-spring</strong> if you are using Maven.<br clear="none"> The reasons is that we leverage Spring's <a shape="rect" class="external-link" href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/util/AntPathMatcher.html" rel="nofollow">AntPathMatcher</a> to do the actual matching.</p><p>The file paths is matched with the following rules:</p><ul class="alternate"><li><p><code>?</code> matches one character</p></li><li><p><code>*</code> matches zero or more characters</p></li><li><p><code>**</code> matches zero or more directories in a path</p></li></ul><p>The sample below demonstrates how to use it: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;camelContext xmlns=&quot;http://camel.apache.org/schema/spring&quot;&gt; &lt;template id=&quot;camelTemplate&quot;/&gt; &lt;!-- use myFilter as filter to allow setting ANT paths for which files to scan for --&gt; &lt;endpoint id=&quot;myFileEndpoint&quot; uri=&quot;file://target/antpathmatcher?recursive=true&amp;amp;filter=#myAntFilter&quot;/&gt; &lt;route&gt; &lt;from ref=&quot;myFileEndpoint&quot;/&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; &lt;/camelContext&gt; &lt;!-- we use the antpath file filter to use ant paths for includes and exlucde --&gt; &lt;bean id=&quot;myAntFilter&quot; class=&quot;org.apache.camel.component.file.AntPathMatcherGenericFileFilter&quot;&gt; &lt;!-- include and file in the subfolder that has day in the name --&gt; &lt;property name=&quot;includes&quot; value=&quot;**/subfolder/**/*day*&quot;/&gt; &lt;!-- exclude all files with bad in name or .xml files. Use comma to seperate multiple excludes --&gt; &lt;property name=&quot;excludes&quot; value=&quot;**/*bad*,**/*.xml&quot;/&gt; &lt;/bean&gt; </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h3 id="BookComponentAppendix-SortingusingComparator">Sorting using <code>Comparator</code></h3><p>Camel supports pluggable sorting strategies. This strategy it to use the build in <strong><code>java.util.Comparator</code></strong> in Java. You can then configure the endpoint with such a comparator and have Camel sort the files before being processed.</p><p>In the sample we have built our own comparator that just sorts by file name: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> public class MyFileSorter&lt;T&gt; implements Comparator&lt;GenericFile&lt;T&gt;&gt; { public int compare(GenericFile&lt;T&gt; o1, GenericFile&lt;T&gt; o2) { return o1.getFileName().compareToIgnoreCase(o2.getFileName()); } } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And then we can configure our route using the <strong>sorter</strong> option to reference to our sorter (<code>mySorter</code>) we have defined in the spring XML file:<div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;!-- define our sorter as a plain spring bean --&gt; &lt;bean id=&quot;mySorter&quot; class=&quot;com.mycompany.MyFileSorter&quot;/&gt; &lt;route&gt; &lt;from uri=&quot;file://inbox?sorter=#mySorter&quot;/&gt; &lt;to uri=&quot;bean:processInbox&quot;/&gt; &lt;/route&gt; </script> @@ -1423,10 +1345,8 @@ cometds://localhost:8443/service/mychann <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">sortBy=date:file:yyyyMMdd;reverse:file:name </script> </div> </div><h3 id="BookComponentAppendix-UsingGenericFileProcessStrategy">Using <code>GenericFileProcessStrategy</code></h3><p>The option <strong><code>processStrategy</code></strong> can be used to use a custom <strong><code>GenericFileProcessStrategy</code></strong> that allows you to implement your own <em>begin</em>, <em>commit</em> and <em>rollback</em> logic.<br clear="none"> For instance lets assume a system writes a file in a folder you should consume. But you should not start consuming the file before another <em>ready</em> file has been written as well.</p><p>So by implementing our own <strong><code>GenericFileProcessStrategy</code></strong> we can implement this as:</p><ul class="alternate"><li><p>In the <strong><code>begin()</code></strong> method we can test whether the special <em>ready</em> file exists. The begin method returns a <code>boolean</code> to indicate if we can consume the file or not.</p></li><li><p>In the <strong><code>abort()</code></strong> method (<str ong>Camel 2.10</strong>) special logic can be executed in case the <strong><code>begin</code></strong> operation returned <strong><code>false</code></strong>, for example to cleanup resources etc.</p></li><li><p>In the <strong><code>commit()</code></strong> method we can move the actual file and also delete the <em>ready</em> file.</p></li></ul><h3 id="BookComponentAppendix-Usingfilter">Using <code>filter</code></h3><p>The <strong><code>filter</code></strong> option allows you to implement a custom filter in Java code by implementing the <strong><code>org.apache.camel.component.file.GenericFileFilter</code></strong> interface. This interface has an <strong><code>accept</code></strong> method that returns a boolean. Return <strong><code>true</code></strong> to include the file, and <strong><code>false</code></strong> to skip the file. From Camel 2.10 onward, there is a <strong><code>isDirectory</code></strong> method on <strong><code>GenericFile</code></strong> whether the file is a directory. This allows you to filter unwanted directories, to avoid traversing down unwanted directories.</p><p>For example to skip any directories which starts with <code>"skip"</code> in the name, can be implemented as follows: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> public class MyDirectoryFilter&lt;T&gt; implements GenericFileFilter&lt;T&gt; { public boolean accept(GenericFile&lt;T&gt; file) { // remember the name due unit testing (should not be needed in regular use-cases) names.add(file.getFileName()); // we dont accept any files within directory starting with skip in the name if (file.isDirectory() &amp;&amp; file.getFileName().startsWith(&quot;skip&quot;)) { return false; } return true; } } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h3 id="BookComponentAppendix-HowtousetheCamelerrorhandlertodealwithexceptionstriggeredoutsidetheroutingengine">How to use the Camel error handler to deal with exceptions triggered outside the routing engine</h3><p>The file and ftp consumers, will by default try to pickup files. Only if that is successful then a Camel <a shape="rect" href="exchange.html">Exchange</a> can be created and passed in the Camel routing engine. When the <a shape="rect" href="exchange.html">Exchange</a> is processed by the routing engine, then the Camel <a shape="rect" href="error-handling-in-camel.html">Error Handling</a> takes over e.g., the <strong><code>onException</code></strong> / <strong><code>errorHandler</code></strong> in the routes. However outside the scope of the routing engine, any exceptions handling is component specific. Camel offers a <strong><code>org.apache.camel.spi.ExceptionHandler</code></strong> that allows components to use that as a pluggable hook for end users to use their own implementation. Camel offers a default <strong><code>LoggingExceptionHandler</code></strong> that will log the exception at <strong><code>ERROR</code>/<code>WARN</code></strong> level.</p><p><br clear="none"> For the file and ftp components this would be the case. However if you want to bridge the <strong><code>ExceptionHandler</code></strong> so it uses the Camel <a shape="rect" href="error-handling-in-camel.html">Error Handling</a>, then you need to implement a custom <strong><code>ExceptionHandler</code></strong> that will handle the exception by creating a Camel <a shape="rect" href="exchange.html">Exchange</a> and send it to the routing engine; then the error handling of the routing engine can get triggered.</p><div class="confluence-information-macro confluence-information-macro-tip"> <p class="title">Easier with Camel 2.10</p> <span class="aui-icon aui-icon-small aui-iconfont-approve confluence-information-macro-icon"></span> @@ -1434,29 +1354,14 @@ cometds://localhost:8443/service/mychann <p>The new option <strong><code>consumer.bridgeErrorHandler</code></strong> can be set to true, to make this even easier. See further below for more details.</p> </div> </div><p>Here is such an example based upon an unit test.</p><p>First we have a custom <strong><code>ExceptionHandler</code></strong> where you can see we deal with the exception by sending it to a Camel <a shape="rect" href="endpoint.html">Endpoint</a> named <strong><code>direct:file-error</code></strong>: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"> - <b>MyExceptionHandler</b> - </div> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> /** * Custom {@link ExceptionHandler} to be used on the file consumer, to send * exceptions to a Camel route, to let Camel deal with the error. */ private static class MyExceptionHandler implements ExceptionHandler { private ProducerTemplate template; /** * We use a producer template to send a message to the Camel route */ public void setTemplate(ProducerTemplate template) { this.template = template; } @Override public void handleException(Throwable exception) { handleException(exception.getMessage(), exception); } @Override public void handleException(String message, Throwable exception) { handleException(exception.getMessage(), null, exception); } @Override public void handleException(final String message, final Exchange originalExchange, final Throwable exception) { // send the message to the special direct:file-error endpoint, which will trigger exception handling // template.send(&quot;d irect:file-error&quot;, new Processor() { @Override public void process(Exchange exchange) throws Exception { // set an exception on the message from the start so the error handling is triggered exchange.setException(exception); exchange.getIn().setBody(message); } }); } } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div> <p>Then we have a Camel route that uses the Camel routing error handler, which is the <strong><code>onException</code></strong> where we handle any <strong><code>IOException</code></strong> being thrown. We then send the message to the same <strong><code>direct:file-error</code></strong> endpoint, where we handle it by transforming it to a message, and then being sent to a <a shape="rect" href="mock.html">Mock</a> endpoint. This is just for testing purpose. You can handle the exception in any custom way you want, such as using a <a shape="rect" href="bean.html">Bean</a> or sending an email, etc.</p><p>Notice how we configure our custom <strong><code>MyExceptionHandler</code></strong> by using the <strong><code>consumer.exceptionHandler</code></strong> option to refer to <strong><code>#myExceptionHandler</code></strong> which is a id of the bean registered in the <a shape="rect" href="registry.html">Registry</a>. If using Spring XML or OSGi Blueprint, then that would be a <strong><code><bean id="myExceptionHandler" class="com.foo.MyExceptionHandler"/></code></strong>: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"> - <b>Camel route with routing engine error handling</b> - </div> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { // to handle any IOException being thrown onException(IOException.class) .handled(true) .log(&quot;IOException occurred due: ${exception.message}&quot;) // as we handle the exception we can send it to direct:file-error, // where we could send out alerts or whatever we want .to(&quot;direct:file-error&quot;); // special route that handles file errors from(&quot;direct:file-error&quot;) .log(&quot;File error route triggered to deal with exception ${exception?.class}&quot;) // as this is based on unit test just transform a message and send it to a mock .transform().simple(&quot;Error ${exception.message}&quot;) .to(&quot;mock:error&quot;); // this is the file route that pickup files, notice how we use our custom exception handler on the consumer // the exclusiveReadLockStrategy is only configured because this is from an unit test, so we use that to simulate exceptions from(&quot;file:target/nospace?exclusiveReadLockStrategy=#myReadLockStrategy&amp;consumer.exceptionHandler=#myExceptionHandler&quot;) .convertBodyTo(String.class) .to(&quot;mock:result&quot;); } }; } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div> <p>The source code for this example can be seen <a shape="rect" class="external-link" href="https://svn.apache.org/repos/asf/camel/trunk/camel-core/src/test/java/org/apache/camel/component/file/FileConsumerCustomExceptionHandlerTest.java">here</a></p><h4 id="BookComponentAppendix-Usingconsumer.bridgeErrorHandler">Using <code>consumer.bridgeErrorHandler</code></h4><p><strong>Available as of Camel 2.10</strong></p><p>If you want to use the Camel <a shape="rect" href="error-handler.html">Error Handler</a> to deal with any exception occurring in the file consumer, then you can enable the <strong><code>consumer.bridgeErrorHandler</code></strong> option as shown below: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"> - <b>Using consumer.bridgeErrorHandler</b> - </div> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { // to handle any IOException being thrown onException(IOException.class) .handled(true) .log(&quot;IOException occurred due: ${exception.message}&quot;) .transform().simple(&quot;Error ${exception.message}&quot;) .to(&quot;mock:error&quot;); // this is the file route that pickup files, notice how we bridge the consumer to use the Camel routing error handler // the exclusiveReadLockStrategy is only configured because this is from an unit test, so we use that to simulate exceptions from(&quot;file:target/nospace?exclusiveReadLockStrategy=#myReadLockStrategy&amp;consumer.bridgeErrorHandler=true&quot;) .convertBodyTo(String.class) .to(&quot;mock:result&quot;); } }; } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>So all you have to do is to enable this option, and the error handler in the route will take it from there.<div class="confluence-information-macro confluence-information-macro-information"> <p class="title">Important when using consumer.bridgeErrorHandler</p> <span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span> @@ -1566,10 +1471,8 @@ cometds://localhost:8443/service/mychann <div class="codeContent panelContent pdl"> <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">Dear ${headers.lastName}, ${headers.firstName} Thanks for the order of ${headers.item}. Regards Camel Riders Bookstore ${body} </script> </div> -</div><p>And the java code:</p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> private Exchange createLetter() { Exchange exchange = context.getEndpoint(&quot;direct:a&quot;).createExchange(); Message msg = exchange.getIn(); msg.setHeader(&quot;firstName&quot;, &quot;Claus&quot;); msg.setHeader(&quot;lastName&quot;, &quot;Ibsen&quot;); msg.setHeader(&quot;item&quot;, &quot;Camel in Action&quot;); msg.setBody(&quot;PS: Next beer is on me, James&quot;); return exchange; } @Test public void testFreemarkerLetter() throws Exception { MockEndpoint mock = getMockEndpoint(&quot;mock:result&quot;); mock.expectedMessageCount(1); mock.message(0).body().contains(&quot;Dear Ibsen, Claus&quot;); mock.message(0).body().contains(&quot;Thanks for the order of Camel in Action.&quot;); template.send(&quot;direct:a&quot;, createLetter()); mock.assertIsSatisfied(); } protected RouteBuilder createRoute Builder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { from(&quot;direct:a&quot;) .to(&quot;freemarker:org/apache/camel/component/freemarker/letter.ftl&quot;) .to(&quot;mock:result&quot;); } }; } </script> - </div> +</div><p>And the java code:</p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><p></p><h3 id="BookComponentAppendix-SeeAlso.18">See Also</h3> <ul><li><a shape="rect" href="configuring-camel.html">Configuring Camel</a></li><li><a shape="rect" href="component.html">Component</a></li><li><a shape="rect" href="endpoint.html">Endpoint</a></li><li><a shape="rect" href="getting-started.html">Getting Started</a></li></ul><h2 id="BookComponentAppendix-FTP/SFTP/FTPSComponent">FTP/SFTP/FTPS Component</h2><p>This component provides access to remote file systems over the FTP and SFTP protocols.</p><p>Maven users will need to add the following dependency to their <code>pom.xml</code> for this component:</p><div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> @@ -1680,10 +1583,8 @@ cometds://localhost:8443/service/mychann <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">230 Logged on TYPE A 200 Type set to A SYST 215 UNIX emulated by FileZilla PORT 127,0,0,1,4,122 200 Port command successful LIST one/two 150 Opening data channel for directory list 226 Transfer OK PORT 127,0,0,1,4,123 200 Port command successful LIST one/two/sub-a 150 Opening data channel for directory list 226 Transfer OK PORT 127,0,0,1,4,124 200 Port command successful LIST one/two/sub-b 150 Opening data channel for directory list 226 Transfer OK PORT 127,0,0,1,4,125 200 Port command successful RETR one/two/foo.txt 150 Opening data channel for file transfer. 226 Transfer OK PORT 127,0,0,1,4,126 200 Port command successful RETR one/two/sub-a/a.txt 150 Opening data channel for file transfer. 226 Transfer OK PORT 127,0,0,1,4,127 200 Port command successful RETR one/two/sub-b/b.txt 150 Opening data channel for file transfer. 226 Transfer OK QUIT 221 Goodbye disconnected. </script> </div> </div><p>As you can see when not using stepwise, there are no CD operation invoked at all.</p><h3 id="BookComponentAppendix-Samples.3">Samples</h3><p>In the sample below we set up Camel to download all the reports from the FTP server once every hour (60 min) as BINARY content and store it as files on the local file system. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { // we use a delay of 60 minutes (eg. once pr. hour we poll the FTP server long delay = 3600000; // from the given FTP server we poll (= download) all the files // from the public/reports folder as BINARY types and store this as files // in a local directory. Camel will use the filenames from the FTPServer // notice that the FTPConsumer properties must be prefixed with &quot;consumer.&quot; in the URL // the delay parameter is from the FileConsumer component so we should use consumer.delay as // the URI parameter name. The FTP Component is an extension of the File Component. from(&quot;ftp://tiger:scott@localhost/public/reports?binary=true&amp;consumer.delay=&quot; + delay). to(&quot;file://target/test-reports&quot;); } }; } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And the route using Spring DSL:<div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;route&gt; &lt;from uri=&quot;ftp://scott@localhost/public/reports?password=tiger&amp;amp;binary=true&amp;amp;delay=60000&quot;/&gt; &lt;to uri=&quot;file://target/test-reports&quot;/&gt; &lt;/route&gt; </script> @@ -1697,19 +1598,15 @@ cometds://localhost:8443/service/mychann <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter">from(&quot;ftps://admin@localhost:2222/public/camel?password=admin&amp;ftpClient.trustStore.file=./src/test/resources/server.jks&amp;ftpClient.trustStore.password=password&quot;) .to(&quot;bean:foo&quot;); </script> </div> </div><h3 id="BookComponentAppendix-Filterusingorg.apache.camel.component.file.GenericFileFilter.1">Filter using <code>org.apache.camel.component.file.GenericFileFilter</code></h3><p>Camel supports pluggable filtering strategies. This strategy can be provided by implementing <code>org.apache.camel.component.file.GenericFileFilter</code> in Java. You can then configure the endpoint with such a filter to skip certain filters before being processed.</p><p>In the sample we have built our own filter that only accepts files starting with report in the filename. - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"> public class MyFileFilter&lt;T&gt; implements GenericFileFilter&lt;T&gt; { public boolean accept(GenericFile&lt;T&gt; file) { // we only want report files return file.getFileName().startsWith(&quot;report&quot;); } } </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div>And then we can configure our route using the <strong>filter</strong> attribute to reference our filter (using <code>#</code> notation) that we have defined in the spring XML file:<div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;!-- define our sorter as a plain spring bean --&gt; &lt;bean id=&quot;myFilter&quot; class=&quot;com.mycompany.MyFileFilter&quot;/&gt; &lt;route&gt; &lt;from uri=&quot;ftp://someu...@someftpserver.com?password=secret&amp;amp;filter=#myFilter&quot;/&gt; &lt;to uri=&quot;bean:processInbox&quot;/&gt; &lt;/route&gt; </script> </div> </div><h3 id="BookComponentAppendix-FilteringusingANTpathmatcher.1">Filtering using ANT path matcher</h3><p>The ANT path matcher is a filter that is shipped out-of-the-box in the <strong>camel-spring</strong> jar. So you need to depend on <strong>camel-spring</strong> if you are using Maven.<br clear="none"> The reason is that we leverage Spring's <a shape="rect" class="external-link" href="http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/util/AntPathMatcher.html" rel="nofollow">AntPathMatcher</a> to do the actual matching.</p><p>The file paths are matched with the following rules:</p><ul class="alternate"><li><code>?</code> matches one character</li><li><code>*</code> matches zero or more characters</li><li><code>**</code> matches zero or more directories in a path</li></ul><p>The sample below demonstrates how to use it: - </p><div class="code panel pdl" style="border-width: 1px;"> - <div class="codeContent panelContent pdl"> - <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"> &lt;bean class=&quot;org.springframework.beans.factory.config.PropertyPlaceholderConfigurer&quot;/&gt; &lt;camelContext xmlns=&quot;http://camel.apache.org/schema/spring&quot;&gt; &lt;template id=&quot;camelTemplate&quot;/&gt; &lt;!-- use myFilter as filter to allow setting ANT paths for which files to scan for --&gt; &lt;endpoint id=&quot;myFTPEndpoint&quot; uri=&quot;ftp://admin@localhost:${SpringFileAntPathMatcherRemoteFileFilterTest.ftpPort}/antpath?password=admin&amp;amp;recursive=true&amp;amp;delay=10000&amp;amp;initialDelay=2000&amp;amp;filter=#myAntFilter&quot;/&gt; &lt;route&gt; &lt;from ref=&quot;myFTPEndpoint&quot;/&gt; &lt;to uri=&quot;mock:result&quot;/&gt; &lt;/route&gt; &lt;/camelContext&gt; &lt;!-- we use the AntPathMatcherRemot eFileFilter to use ant paths for includes and exclude --&gt; &lt;bean id=&quot;myAntFilter&quot; class=&quot;org.apache.camel.component.file.AntPathMatcherGenericFileFilter&quot;&gt; &lt;!-- include any files in the sub folder that has day in the name --&gt; &lt;property name=&quot;includes&quot; value=&quot;**/subfolder/**/*day*&quot;/&gt; &lt;!-- exclude all files with bad in name or .xml files. Use comma to separate multiple excludes --&gt; &lt;property name=&quot;excludes&quot; value=&quot;**/*bad*,**/*.xml&quot;/&gt; &lt;/bean&gt; </script> - </div> + </p><div class="error"> + <span class="error">Error formatting macro: snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20</span> </div><h3 id="BookComponentAppendix-UsingaproxywithSFTP">Using a proxy with SFTP</h3><p>To use an HTTP proxy to connect to your remote host, you can configure your route in the following way:</p><div class="code panel pdl" style="border-width: 1px;"> <div class="codeContent panelContent pdl"> <script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter">&lt;!-- define our sorter as a plain spring bean --&gt; &lt;bean id=&quot;proxy&quot; class=&quot;com.jcraft.jsch.ProxyHTTP&quot;&gt; &lt;constructor-arg value=&quot;localhost&quot;/&gt; &lt;constructor-arg value=&quot;7777&quot;/&gt; &lt;/bean&gt; &lt;route&gt; &lt;from uri=&quot;sftp://localhost:9999/root?username=admin&amp;password=admin&amp;proxy=#proxy&quot;/&gt; &lt;to uri=&quot;bean:processFile&quot;/&gt; &lt;/route&gt; </script> @@ -2359,18 +2256,12 @@ cometds://localhost:8443/service/mychann <div class="codeContent panelContent pdl">
[... 908 lines stripped ...]