Author: buildbot Date: Thu Nov 27 19:19:39 2014 New Revision: 930799 Log: Production update by buildbot for camel
Modified: websites/production/camel/content/cache/main.pageCache websites/production/camel/content/camel-and-scr.html Modified: websites/production/camel/content/cache/main.pageCache ============================================================================== Binary files - no diff available. Modified: websites/production/camel/content/camel-and-scr.html ============================================================================== --- websites/production/camel/content/camel-and-scr.html (original) +++ websites/production/camel/content/camel-and-scr.html Thu Nov 27 19:19:39 2014 @@ -151,7 +151,113 @@ public class CamelScrExample extends Abs return routesBuilders; } }]]></script> -</div></div><p> </p><p><code style="font-size: 14.0px;line-height: 1.4285715;">CamelContextId</code><span style="font-size: 14.0px;line-height: 1.4285715;"> and </span><code style="font-size: 14.0px;line-height: 1.4285715;">active</code><span style="font-size: 14.0px;line-height: 1.4285715;"> properties control the CamelContext's name (defaults to "camel-runner-default") and whether it will be started or not (defaults to "false"), respectively. In addition to these you can add and use as many properties as you like. Camel's PropertiesComponent handles recursive properties and prefixing with fallback without problem.</span></p><p><code>AbstractCamelRunner</code> will make these properties available to your RouteBuilders with help of Camel's PropertiesComponent and it will also inject these values into your Service Component's and RouteBuilder's fields when their names match. The fields can be declared with any visibility level, and many types are supported (String , int, boolean, URL, ...).</p><h4 id="CamelandSCR-AbstractCamelRunner'slifecycleinSCR">AbstractCamelRunner's lifecycle in SCR</h4><ol><li>When component's configuration policy and mandatory references are satisfied SCR calls <code>activate()</code>. This creates and sets up a CamelContext through the following call chain: <code>activate()</code> → <code>prepare()</code> → <code>createCamelContext()</code> → <code>setupPropertiesComponent()</code> → <code>configure()</code> → <code>setupCamelContext()</code>. Finally, the context is scheduled to start after a delay defined in <code>AbstractCamelRunner.START_DELAY</code> with <code>runWithDelay()</code>.</li><li><span style="line-height: 1.4285715;">When Camel components (<code>ComponentResolver</code> services, to be exact) are registered in OSGi, SCR calls </span><code>gotCamelComponent</code><span style="line-height: 1.4285715;"><code>()</code> which reschedules/ delays the CamelContext start further by the same </span><code>AbstractCamelRunner.START_DELAY</code><span style="line-height: 1.4285715;">. This in effect makes CamelContext wait until all Camel components are loaded or there is a sufficient gap between them. The same logic will tell a failed-to-start CamelContext to try again whenever we add more Camel components.</span></li><li><span style="line-height: 1.4285715;">When Camel components are unregistered SCR calls </span><code>lostCamelComponent</code><span style="line-height: 1.4285715;"><code>()</code>. This call does nothing.</span></li><li><span style="line-height: 1.4285715;">When one of the requirements that caused the call to </span><code>activate</code><span style="line-height: 1.4285715;"><code>()</code> is lost SCR will call </span><code>deactivate</code><span style="line-height: 1.4285715;"><code>()</code>. This will shutdown the CamelContext.</span></li></ol><p>In (non-OSGi) unit tests you should use <code>prepare()</c ode> → <code>run()</code> → <code>stop()</code> instead of <code>activate()</code> → <code>deactivate()</code> for more fine-grained control. Also, this allows us to avoid possible SCR specific operations in tests.</p><h3 id="CamelandSCR-Usingcamel-archetype-scr">Using camel-archetype-scr</h3><p>The easiest way to create an Camel SCR bundle project is to use <code>camel-archetype-scr</code> and Maven.</p><p>You can generate a project with the following steps:</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Generating a project</b></div><div class="codeContent panelContent pdl"> +</div></div><p> </p><p><code style="font-size: 14.0px;line-height: 1.4285715;">CamelContextId</code><span style="font-size: 14.0px;line-height: 1.4285715;"> and </span><code style="font-size: 14.0px;line-height: 1.4285715;">active</code><span style="font-size: 14.0px;line-height: 1.4285715;"> properties control the CamelContext's name (defaults to "camel-runner-default") and whether it will be started or not (defaults to "false"), respectively. In addition to these you can add and use as many properties as you like. Camel's PropertiesComponent handles recursive properties and prefixing with fallback without problem.</span></p><p><code>AbstractCamelRunner</code> will make these properties available to your RouteBuilders with help of Camel's PropertiesComponent and it will also inject these values into your Service Component's and RouteBuilder's fields when their names match. The fields can be declared with any visibility level, and many types are supported (String , int, boolean, URL, ...).</p><p>Below is an example of a RouteBuilder class generated by <code>camel-archetype-scr</code>:</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>CamelScrExampleRoute.java</b></div><div class="codeContent panelContent pdl"> +<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[// This file was generated from org.apache.camel.archetypes/camel-archetype-scr/2.15-SNAPSHOT +package example.internal; + +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.SimpleRegistry; +import org.apache.commons.lang.Validate; + +public class CamelScrExampleRoute extends RouteBuilder { + + SimpleRegistry registry; + + // Configured fields + private String camelRouteId; + private Integer maximumRedeliveries; + private Long redeliveryDelay; + private Double backOffMultiplier; + private Long maximumRedeliveryDelay; + + public CamelScrExampleRoute(final SimpleRegistry registry) { + this.registry = registry; + } + + @Override + public void configure() throws Exception { + checkProperties(); + + // Add a bean to Camel context registry + registry.put("test", "bean"); + + errorHandler(defaultErrorHandler() + .retryAttemptedLogLevel(LoggingLevel.WARN) + .maximumRedeliveries(maximumRedeliveries) + .redeliveryDelay(redeliveryDelay) + .backOffMultiplier(backOffMultiplier) + .maximumRedeliveryDelay(maximumRedeliveryDelay)); + + from("{{from}}") + .startupOrder(2) + .routeId(camelRouteId) + .onCompletion() + .to("direct:processCompletion") + .end() + .removeHeaders("CamelHttp*") + .to("{{to}}"); + + + from("direct:processCompletion") + .startupOrder(1) + .routeId(camelRouteId + ".completion") + .choice() + .when(simple("${exception} == null")) + .log("{{messageOk}}") + .otherwise() + .log(LoggingLevel.ERROR, "{{messageError}}") + .end(); + } + } + + public void checkProperties() { + Validate.notNull(camelRouteId, "camelRouteId property is not set"); + Validate.notNull(maximumRedeliveries, "maximumRedeliveries property is not set"); + Validate.notNull(redeliveryDelay, "redeliveryDelay property is not set"); + Validate.notNull(backOffMultiplier, "backOffMultiplier property is not set"); + Validate.notNull(maximumRedeliveryDelay, "maximumRedeliveryDelay property is not set"); + } +}]]></script> +</div></div><p> </p><p>Let's take a look at CamelScrExampleRoute in more detail.</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[ // Configured fields + private String camelRouteId; + private Integer maximumRedeliveries; + private Long redeliveryDelay; + private Double backOffMultiplier; + private Long maximumRedeliveryDelay;]]></script> +</div></div><p>The values of these fields are set with values from properties by matching their names.</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[ // Add a bean to Camel context registry + registry.put("test", "bean");]]></script> +</div></div><p>If you need to add some beans to CamelContext's registry for your routes, you can do it like this.</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[ public void checkProperties() { + Validate.notNull(camelRouteId, "camelRouteId property is not set"); + Validate.notNull(maximumRedeliveries, "maximumRedeliveries property is not set"); + Validate.notNull(redeliveryDelay, "redeliveryDelay property is not set"); + Validate.notNull(backOffMultiplier, "backOffMultiplier property is not set"); + Validate.notNull(maximumRedeliveryDelay, "maximumRedeliveryDelay property is not set"); + }]]></script> +</div></div><p>It is a good idea to check that required parameters are set and they have meaningful values before allowing the routes to start.</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> +<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[ from("{{from}}") + .startupOrder(2) + .routeId(camelRouteId) + .onCompletion() + .to("direct:processCompletion") + .end() + .removeHeaders("CamelHttp*") + .to("{{to}}"); + + + from("direct:processCompletion") + .startupOrder(1) + .routeId(camelRouteId + ".completion") + .choice() + .when(simple("${exception} == null")) + .log("{{messageOk}}") + .otherwise() + .log(LoggingLevel.ERROR, "{{messageError}}") + .end();]]></script> +</div></div><p>Note that pretty much everything in the route is configured with properties. This essentially makes your RouteBuilder a template. SCR allows you to create more instances of your routes just by providing alternative configurations. More on this in section <em>Using Camel SCR bundle as a template</em>.</p><h4 id="CamelandSCR-AbstractCamelRunner'slifecycleinSCR">AbstractCamelRunner's lifecycle in SCR</h4><ol><li>When component's configuration policy and mandatory references are satisfied SCR calls <code>activate()</code>. This creates and sets up a CamelContext through the following call chain: <code>activate()</code> → <code>prepare()</code> → <code>createCamelContext()</code> → <code>setupPropertiesComponent()</code> → <code>configure()</code> → <code>setupCamelContext()</code>. Finally, the context is scheduled to start after a delay defined in <code>AbstractCamelRunner.START_DELAY</code> with <code >runWithDelay()</code>.</li><li><span style="line-height: 1.4285715;">When >Camel components (<code>ComponentResolver</code> services, to be exact) are >registered in OSGi, SCR calls </span><code>gotCamelComponent</code><span >style="line-height: 1.4285715;"><code>()</code> which reschedules/delays the >CamelContext start further by the same ></span><code>AbstractCamelRunner.START_DELAY</code><span style="line-height: >1.4285715;">. This in effect makes CamelContext wait until all Camel >components are loaded or there is a sufficient gap between them. The same >logic will tell a failed-to-start CamelContext to try again whenever we add >more Camel components.</span></li><li><span style="line-height: >1.4285715;">When Camel components are unregistered SCR calls ></span><code>lostCamelComponent</code><span style="line-height: >1.4285715;"><code>()</code>. This call does nothing.</span></li><li><span >style="line-height: 1.4285715;">When one of the requirements that caused the >call to </span><code> activate</code><span style="line-height: 1.4285715;"><code>()</code> is lost SCR will call </span><code>deactivate</code><span style="line-height: 1.4285715;"><code>()</code>. This will shutdown the CamelContext.</span></li></ol><p>In (non-OSGi) unit tests you should use <code>prepare()</code> → <code>run()</code> → <code>stop()</code> instead of <code>activate()</code> → <code>deactivate()</code> for more fine-grained control. Also, this allows us to avoid possible SCR specific operations in tests.</p><h3 id="CamelandSCR-Usingcamel-archetype-scr">Using camel-archetype-scr</h3><p>The easiest way to create an Camel SCR bundle project is to use <code>camel-archetype-scr</code> and Maven.</p><p>You can generate a project with the following steps:</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Generating a project</b></div><div class="codeContent pan elContent pdl"> <script class="theme: Default; brush: text; gutter: false" type="syntaxhighlighter"><![CDATA[$ mvn archetype:generate -Dfilter=org.apache.camel.archetypes:camel-archetype-scr  Choose archetype: @@ -322,7 +428,7 @@ public class CamelScrExampleTest { </div></div><p>Here we start the Service Component and along with it the routes.</p><p> </p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Sending a test message</b></div><div class="codeContent panelContent pdl"> <script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[ // Send the test message context.createProducerTemplate().sendBody("direct:start", "hello");]]></script> -</div></div><p>Here we send a message to a route in test.</p></div> +</div></div><p>Here we send a message to a route in test.</p><h3 id="CamelandSCR-UsingCamelSCRbundleasatemplate">Using Camel SCR bundle as a template</h3><p>TODO</p></div> </td> <td valign="top"> <div class="navigation">