-
Language:
English
-
Language:
English
Red Hat Training
A Red Hat training course is available for Red Hat Fuse
Tooling Tutorials
Building Solutions with Red Hat JBoss Fuse Tooling
Red Hat
Copyright © 2011-2015 Red Hat, Inc. and/or its affiliates.
Abstract
Chapter 1. Using the Fuse Tooling Resource Files
Abstract
Prerequisites
Downloading and installing the Prefabricated message files
message1.xml
, message2.xml
,..., message6.xml
are used in all of the tutorials. These files are provided in a downloadable Messages.zip
file. Follow the instructions for downloading and installing the messages in the section called “Creating test messages”.
Downloading and installing the prefabricated Camel Context files
camelContext5.xml
, and camelContext6.xml
are used in one or more of the tutorials. These files are provided in a downloadable .zip file.
- Click here to download the
camelContexts.zip
file. - Unzip the
camelContexts.zip
file in a convenient location external to the CBRroute project's workspace. - Delete the existing
camelContext.xml
file from theCBRroute/src/main/resources/OSGI-INF/blueprint/
folder. - Install the
camelContext#.xml
file that corresponds to the tutorial that you want to complete in the vacatedCBRroute/src/main/resources/OSGI-INF/blueprint/
folder.Use prefabricated Camel Context file: To complete tutorials: camelContext5.xml
To Add Another Route to the CBR Routing Context camelContext6.xml
To Debug a Routing ContextTo Trace a Message Through a RouteTo Test a Route with JUnit - Rename the
camelContext#.xml
filecamelContext.xml
. - In the Red Hat JBoss Fuse: Tooling Tutorials guide, follow the instructions for completing the target tutorial.
Chapter 2. To Create a New Route
Abstract
Goals
- create a Fuse project
- create a new routing context
- create a route
- add endpoints to the route
- connect the endpoints
- configure the endpoints
- create a folder in your project to store test messages that you create for your route
- create the test messages
Prerequisites
Figure 2.1. JBoss View on initial startup
- Close the JBoss Central tab.NoteYou can reopen a view whenever you need it. You can also drag the border of a view or panel to increase or decrease the space it occupies in the workspace.
- Close the JMX Navigator view at bottom, left of the workspace.
- Drag Outline view from top, right of the workspace, and drop it in the spot previously occupied by the JMX Navigator view.
Figure 2.2. JBoss View rearranged
Creating the Fuse project
- On the Toolbar, select File → New → Fuse Project to open the New Fuse project wizard, as shown in Figure 2.3.
Figure 2.3. New Fuse project location page
- Enter
CBRroute
in the Project Name field. Figure 2.4. New Fuse project details page
- Select
camel-archetype-blueprint
. - Enter
tutorial
in the Group Id: field. - Enter
cbr-route
in the Artifact Id: field. - The Version: field defaults to
1.0.0-SNAPSHOT
. To change it, enter a different version identifier. - The Package: field defaults to
tutorial.cbr.route
, the name of the package that containscamel-archetype-blueprint
. To include the route in a different package, enter the name of that package. - Click Finish.NoteClick No when the Open Associated Perspective? dialog asks whether you want to open the Fuse Integration perspective now.This procedure creates a Fuse project,
CBRroute
, in Project Explorer that contains everything needed to create and run routes. As shown in Figure 2.5, the files generated forCBRroute
include:CBRroute/pom.xml
(Maven project file)CBRroute/src/main/resources/OSGI-INF/blueprint/blueprint.xml
(Blueprint XML file containing the routing rules)Figure 2.5. Generated project files
Creating the new routing context
- In Project Explorer, locate
CBRroute/src/main/resources/OSGI-INF/blueprint/blueprint.xml
. - Right-click it to open the context menu, then select Delete.You're going to replace the old
blueprint.xml
file with your own to create a new route. - In the Delete dialog, click OK to confirm the operation.
- In Project Explorer, select
CBRroute/src/main/resources/OSGI-INF/blueprint
. - Right-click it to open the context menu.
Figure 2.6. Camel XML File wizard
- Check that
/CBRroute/src/main/resources/OSGI-INF/blueprint
appears in the Container: field. Otherwise enter it manually, or select it using the button.NoteThe button opens a dialog that displays the folders of all active projects, which you can browse to find and select the files you need. - Check that
camelContext.xml
appears in the File Name: field. Otherwise enter it manually. - Check that OSGI Blueprint appears in the Framework field, or select it from the field's drop-down list.
- Click Finish.The camelContext.xml file opens in the route editor's Design view, displayed as an empty canvas, as shown in Figure 2.7.
Figure 2.7. New camelContext .xml file in Design view
- Click the Source tab at the bottom, left of the canvas to open the new
camelContext.xml
file in the route editor's Source view, as shown in Figure 2.8, “New camelContext file in source view”.Figure 2.8. New camelContext file in source view
Creating the route
- Click the Design tab at the bottom, left of the canvas to return to the route editor's Design view.
- Drag a File component ( ) from the Palette's Components drawer to the canvas.NoteThe File component changes to a file:directoryNam... node on the canvas.
- Drag another File component from the Palette's Components drawer to the canvas.
- Select the first file:directoryName node you dragged onto the canvas.The Properties editor, located below the canvas, displays the node's property fields for editing.
- Select the Advanced tab, as shown in Figure 2.9.
Figure 2.9. File source property editor
- On the Path tab, click the button next to the Directory Name field, to browse to the
src/data
folder you previously created in your CBRroute project. - Click Open.The full path appears in the Directory Name field.
- Delete everything in the path string, except
src/data
. - Click the Consumer tab, and enable the Noop option by clicking its check box.The Noop option prevents the message#.xml files being deleted from the
src/data
folder, and it enables idempotency to ensure that each message#.xml file is consumed only once. - Click the Generic tab to open the file node's Details page
Figure 2.10. File Details page
The tooling automatically populates the Uri field with the Directory name and Noop properties you configured on the Advanced tab. - Select the second file:directoryName node you dragged onto the canvas.
- In the Generic tab's Uri field, replace directoryName with
target/messages/others
. Leave the other fields blank.Figure 2.11. File destination property editor
NoteThetarget/messages/others
folder will be created at runtime. - On the canvas, select the first file: node (
file:src/data?noop=true
), and drag it's connector arrow ( ) to the second file node (file:target/messages/others
), then release it.A segmented line connects the two endpoints, as shown in Figure 2.12.Figure 2.12. Completed route, diagram view
NoteYou can drag the line's bendpoint (orange dot) to change the angle of the line's segments. Doing so creates two new bendpoints, one on either side of the original. This behavior enables you to easily adjust your diagram to accommodate increasingly complex routes. - To quickly align the connected endpoints, right-click the canvas to open the context menu, and then select Layout Diagram.
- Select File → Save to save the route.
- Click the Source tab at bottom, left of the canvas.
Example 2.1. XML for CBRroute
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:camel="http://camel.apache.org/schema/blueprint" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd"> <camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="file:src/data?noop=true"/> <to uri="file:target/messages/others"/> </route> </camelContext> </blueprint>
Creating test messages
- In Project Explorer, right-click
CBRroute/src
to open the context menu. - Select New → Folder to open the New Folder wizard:
- Check that CBRroute/src appears in the Enter or select the parent folder: field. Otherwise enter it manually, or select it from the graphical representation of the project's hierarchy
- In the Folder name: field, enter data, and then click Finish.The new
data
folder appears in Project Explorer, under thesrc
folder: - In Project Explorer, right-click
CBRroute
to open the context menu. - Click New → Fuse Message to open the Fuse Message File wizard:
- Check that CBRroute/src/data appears in the Enter or select the parent folder field. Otherwise enter it manually, or select it from the graphical representation of the project's hierarchy.
- In File Name:, enter
message1.xml
. - Click Finish to open the test message,
message1.xml
, in Design View: - Click the Source tab at the bottom, right of the canvas to switch to Source view:
- In Source view, enter this text:
<?xml version="1.0" encoding="UTF-8"?> <order> <customer> <name>Brooklyn Zoo</name> <city>Brooklyn</city> <country>USA</country> </customer> <orderline> <animal>wombat</animal> <quantity>15</quantity> <maxAllowed>25</maxAllowed> </orderline> </order>
- Save the file.
- Click Messages.zip to download the five remaining preconstructed test message files (
message2.xml
throughmessage6.xml
), and then unpack them into theCBRroute/src/data
folder. You will use all six test messages in the remaining Fuse Tooling tutorials.Table 2.1 shows the contents of each preconstructed message file.Table 2.1. Preconstructed test messages
msg# <name> <city> <country> <animal> <quantity> <maxAllowed> 2 San Diego Zoo San Diego USA giraffe 3 2 3 London Zoo London Great Britain penguin 12 20 4 Bristol Zoo Bristol Great Britain emu 5 4 5 Paris Zoo Paris France giraffe 2 2 6 Hellabrunn Gardens Munich Germany penguin 18 20
Next steps
Further reading
- using the editor, see Red Hat JBoss Fuse Tooling: JBoss Fuse Tooling User Guide at https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.2/html/Tooling_User_Guide/RiderEditRoute.html
- Apache Camel endpoints, see Red Hat JBoss Fuse: Component Reference.
Chapter 3. To Run a Route
Abstract
Goals
- run a route as a local Apache Camel Context (without tests)
- send messages through the route
- examine the messages received by the endpoints
Prerequisites
Running the route
- Open the CBRroute project you created in the section called “Creating the Fuse project”.
- In Project Explorer, select
CBRroute/src/main/resources/OSGi-INF/blueprint/camelContext.xml
. - Right-click it to open the context menu, then select Run As → Local Camel Context (without tests).NoteIf you select Local Camel Context instead, the tooling automatically runs the routing context against the supplied JUnit test, and it will fail. In the Chapter 8, To Test a Route with JUnit tutorial, you will replace the supplied JUnit test with one you create for the this project.The Console panel opens to display log messages that reflect the progress of the project's execution. At the beginning, Maven downloads the resources necessary to update the local Maven repository, which may take a few minutes.Messages similar to the following indicate that the route executed successfully.
[INFO] Starting Camel ... [mel.test.blueprint.Main.main()] MainSupport INFO Apache Camel 2.13.2 starting [mel.test.blueprint.Main.main()] Activator INFO Camel activator starting [mel.test.blueprint.Main.main()] Activator INFO Camel activator started [mel.test.blueprint.Main.main()] BlueprintExtender INFO No quiesce support is available, so blueprint components will not participate in quiesce operations [ Blueprint Extender: 1] BlueprintContainerImpl INFO Bundle cbr-route is waiting for namespace handlers [http://camel.apache.org/schema/blueprint] [ Blueprint Extender: 1] BlueprintCamelContext INFO Apache Camel 2.13.2 (CamelContext: blueprintContext) is starting [ Blueprint Extender: 1] ManagedManagementStrategy INFO JMX is enabled [heysmbp.home:1099/jmxrmi/camel] DefaultManagementAgent INFO JMX Connector thread started and listening at: service:jmx:rmi:///jndi/rmi://janemurpheysmbp.home:1099/jmxrmi/camel [ Blueprint Extender: 1] BlueprintCamelContext INFO AllowUseOriginalMessage is enabled. If access to the original message is not needed, then its recommended to turn this option off as it may improve performance. [ Blueprint Extender: 1] BlueprintCamelContext INFO StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html [ Blueprint Extender: 1] FileEndpoint INFO Endpoint is configured with noop=true so forcing endpoint to be idempotent as well [ Blueprint Extender: 1] FileEndpoint INFO Using default memory based idempotent repository with cache max size: 1000 [ Blueprint Extender: 1] XPathBuilder INFO Created default XPathFactory com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl@46e48d4 [ Blueprint Extender: 1] BlueprintCamelContext INFO Route: Route1 started and consuming from: Endpoint[file://src/data?noop=true] [ Blueprint Extender: 1] BlueprintCamelContext INFO Total 1 routes, of which 1 is started. [ Blueprint Extender: 1] BlueprintCamelContext INFO Apache Camel 2.13.2 (CamelContext: blueprintContext) started in 1.073 seconds
- To shutdown the route, click located at the top, right of the Console panel.
Verifying the route
- In Project Explorer, select
CBRroute
. - Right-click it to open the context menu, then select Refresh.
Figure 3.1. Target message destination in Project Explorer tree
- Verify that the
target/messages/others
folder contains the six message files,message1.xml
throughmessage6.xml
. - Double-click
message1.xml
to open it in the editor's Design view, then select the Source tab at the bottom, left of the canvas to see the xml code.It's contents should match that shown in Example 3.1.Example 3.1. Contents of message1.xml
<?xml version="1.0" encoding="UTF-8"?> <order> <customer> <name>Brooklyn Zoo</name> <city>Brooklyn</city> <country>USA</country> </customer> <orderline> <animal>wombat</animal> <quantity>15</quantity> <maxAllowed>25</maxAllowed> </orderline> </order>
Further reading
- configuring runtime profiles, see Red Hat JBoss Fuse Tooling: JBoss Fuse Tooling User Guide at https://access.redhat.com/documentation/en-US/Red_Hat_JBoss_Fuse/6.2/html/Tooling_User_Guide/RiderEditRunProfile.html.
- deploying Apache Camel applications see Red Hat JBoss Fuse: Deploying into the Container.
Chapter 4. To Add a Content-Based Router
Abstract
Goals
- add a content-based router to your route
- configure the content-based router
- add a log endpoint to each output branch of the content-based router
- add a SetHeader EIP after each log endpoint
- add an Otherwise branch to the content-based router
Prerequisites
Adding and configuring a content-based router
- In Project Explorer, double-click
CBRroute/src/main/resources/OSGI-INF/blueprint/camelContext.xml
to open your CBRroute project. - Select the connector joining the two file: nodes
file:src/data?noop=true
andfile:target/messages/others
. - Right-click it to open the context menu, and select Remove to delete the connector.NoteAlternatively, you can delete the connector by selecting it, then selecting Delete from the toolbar's Edit menu.
- On the canvas, select the terminal file: node,
file:target/messages/others
, and in the Properties editor, change the Uri and Id properties to:Then drag the node out of the way. You will connect it to another node later in this tutorial.- Uri:—
file:target/messages/validOrders
- Id:—
toValid
- On the canvas, select the starting file: node,
file:src/data?noop=true
, and right-click it to open the context menu. - Select Add → Routing → Choice.A choice node ( ) appears on the canvas connected to the starting file: node.
- In the Properties editor, enter
choice1
in the Id field. - On the canvas, select the choice node, then right-click it to open the context menu.
- Select Add → Routing → When.A when node appears on the canvas connected to the choice node. The Properties editor opens, displaying the when node's property fields for you to edit, as shown:NoteWhen a required property is blank, the Properties editor marks it with . The number of properties that require configuring is displayed in the title bar. Error icons and message disappear when you configure the required properties.
- In the Expression field, enter
/order/orderline/quantity/text() > /order/orderline/maxAllowed/text()
.This expression determines which messages will transit this path in the route. - From the Language drop-down menu, select xpath.
- In the Id field, enter
when1
.Figure 4.1 shows the when1 node configured.Figure 4.1. when1 configuration
Adding and configuring logging
- On the canvas, select the when1 node, and then right-click it to open the context menu.
- Select Add → Components → Log.A log node appears on the canvas, connected to the when1 node. The Properties editor opens, displaying the log node's property fields for you to edit.
- In the Message field, enter
quantity requested exceeds the maximum allowed - contact customer
. - In the Id field, enter
log1
.Figure 4.2 shows the log1 node configured.Figure 4.2. Log1 configuration
NoteIn Fuse Integration perspective's Messages View, the tooling inserts the contents of the log node's Id field in theTrace Node Id
column for message instances, when tracing is enabled on the route (see Figure 7.11, “Fuse Integration perspective's message tracing components”). In the Console, it adds the contents of the log node's Message field to the log data whenever the route runs.
Adding and configuring message headers
- On the canvas, select the log1 node, and then right-click it to open the context menu.
- Select Add → Transformation → SetHeader.A setHeader node ( ) appears on the canvas, connected to the log 1 node. The Properties editor opens, displaying the setHeader node's property fields for you to edit, as shown:
- In the Header Name field, enter
Destination
. - In the Expression field, enter
InvalidOrders
. - Select constant from the Language drop-down menu.
- In the Id field, enter
setHead1
.Figure 4.3 shows the setHead1 node configured.Figure 4.3. setHead1 configuration
- On the canvas, select the setHead1 node, and then right-click it to open the context menu.
- Select Add → Components → File.A file:directoryName node appears on the canvas, connected to the setHead1 node. The Properties editor opens, displaying the file:directoryName node's property fields for you to edit.
- On the Generic tab, replace directoryName with
target/messages/invalidOrders
in the Uri field, and entertoInvalid
in the Id field.
Adding and configuring an otherwise branch
- On the canvas, reselect the Choice node, then right-click it to open the context menu.
- Select Add → Routing → Otherwise.An otherwise node appears on the canvas, connected to the choice node. The Properties editor opens, displaying the otherwise node's property fields for you to edit.
- In the Id field, enter
else2
.The else2 node will eventually route to the terminal file: node (file:target/messages/validOrders
) any message that does not match the XPath expression set for the when1 node. - On the canvas, select the else2 node, and then right-click it to open the context menu.
- Select Add → Components → Log.A log node appears on the canvas, connected to the else2 node. The Properties editor opens, displaying the log node's property fields for you to edit.
- In the Message field, enter
valid order - process
, and in the Id field, enterlog2
. - On the canvas, select the log2 node, and then right-click it to open the context menu.
- Select Add → Transformation → SetHeader.A setHeader node ( ) appears on the canvas, connected to the log2 node. The Properties editor opens, displaying the setHeader node's property fields for you to edit.
- In the Header Name field, enter
Destination
. - In the Expression field, enter
Dispatcher
. - Select constant from the Language drop-down menu.
- In the Id field, enter
setHead2
. - On the canvas, drag the terminal file: node,
file:target/messages/validOrders
, close to the setHead2 node. - Select the setHead2 node, and then drag its connector arrow ( ) to the terminal file: node and release it.
- To quickly realign all of the nodes on the canvas, right-click the canvas to open the context menu, and then select Layout Diagram.The route on the canvas should resemble Figure 4.4.
Figure 4.4. Completed content-based router with logs and message headers
- On the toolbar, select File → Save to save the completed route.
- Click the Source tab at the bottom, left of the canvas to display the XML for the route.The
camelContext
element will look like that shown in Example 4.1.Example 4.1. XML for content-based router
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:camel="http://camel.apache.org/schema/blueprint" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd"> <camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="file:src/data?noop=true"/> <choice id="choice1"> <when id="when1"> <xpath>/order/orderline/quantity/text() > /order/orderline/maxAllowed/text()</xpath> <log message="quantity requested exceeds maximum allowed - contact customer" id="log1"/> <setHeader headerName="Destination" id="setHead1"> <constant>InvalidOrders</constant> </setHeader> <to uri="file:target/messages/invalidOrders" id="toInvalid"/> </when> <otherwise id="else2"> <log message="valid order - process" id="log2"/> <setHeader headerName="Destination" id="setHead2"> <constant>Dispatcher</constant> </setHeader> <to uri="file:target/messages/validOrders" id="toValid"/> </otherwise> </choice> </route> </camelContext> </blueprint>
Next steps
- Select
CBRroute
. - Right-click it to open the context menu, then select Refresh.
- Under the project root node (CBRroute), locate the folder
target/messages/
and expand it, as shown in Figure 4.5.Figure 4.5. Target message destinations in Project Explorer
- Check that the
target/messages/invalidOrders
folder containsmessage2.xml
andmessage4.xml
.In these messages, the value of the quantity element should exceed the value of the maxAllowed element. - Check that the
target/messages/validOrders
folder contains the four message files that contain valid orders:message1.xml
,message3.xml
,message5.xml
andmessage6.xml
.In these messages, the value of the quantity element should be less than or equal to the value of the maxAllowed element.NoteTo view message content, double-click each message to open it in the route editor's xml editor.
Further reading
Chapter 5. To Add Another Route to the CBR Routing Context
Abstract
camelContext.xml
file in the CBRroute project. The second route:
- takes messages directly from the terminal end of the first route's otherwise branch
- sorts the messages according to customers' country
- sends each message to the corresponding
CBRroute/target/messages/<country>
directory
Goals
- reconfigure the existing route for direct connection to a second route
- add a second route to your camelContext
- configure the new route to take messages directly from the otherwise branch of the first route
- add a content-based router to the new route
- add and configure a message header, logging, and target destination to each output branch of the new route's content-based router
Prerequisites
camelContext5.xml
file to work through this tutorial (for details, see Chapter 1, Using the Fuse Tooling Resource Files).
Reconfiguring the existing route for direct connection
- Open your
CBRroute/src/main/resources/OSGI-INF/blueprint/camelContext.xml
in the route editor. - Click the canvas to display the existing route's properties in the Properties editor.
- Enter
Route1
in the Id field. - Select the terminal file: node file:target/messages/toValid to display its properties in the Properties editor.
- In the Uri field, delete the existing text, and then enter
direct:OrderFulfillment
. - In the Id field, enter
toFulfill
.
Adding the second route
- Select Routes → Add Route.The tooling adds another route to your camelContext, and the route editor opens a clean canvas for you to construct the second route.Outline view, shown here, displays both routes and their components. Clicking on a route in Outline view displays it on the route editor's canvas.Or you can switch between routes by selecting Routes → Route:RouteName on the menu bar, where RouteName is the string you entered in the route's Id field in the Properties editor.
- Click the canvas to display the new route's properties in the Properties editor.
- Enter
Route2
in the Id field.
Building and configuring the USA branch of the second route
Route2
displayed on the route editor's canvas:
- Drag an Generic element ( ) from the Palette's Components drawer onto the canvas.
- In the Properties editor, enter
direct:OrderFulfillment
in the Uri field. - Right-click the direct:OrderFulfi... node to open the context menu, and select Add → Routing → Choice.
- In the Properties editor, enter
choice2
in the Id field. - Right-click the choice2 node to open the context menu, and select Add → Routing → When.
- In the Properties editor:
- Enter
/order/customer/country = 'USA'
in the Expression field. - Select
xpath
from the Language drop-down menu. - Enter
when/usa
in the Id field.
- Right-click the when/usa node to open the context menu, and select Add → Transformation → SetHeader.
- In the Properties editor:
- Enter
Destination
in the Header Name field. - Enter
USA
in the Expression field. - Select constant from the Language drop-down menu.
- Enter
setHead_usa
in the Id field,
- Right-click the setHead_usa node to open the context menu, and select Add → Components → Log.
- In the Properties editor:
- Enter
Valid order - ship animals to USA customer
in the Message field. - Enter
log_usa
in the Id field.
- Right-click the log_usa node to open the context menu, and select Add → Components → File.
- In the Properties editor:
- Replace directoryName with
target/messages/USA
in the Uri field. - Enter
toUS
in the Id field.
Building and configuring the Great Britain branch of the second route
Route2
displayed on the canvas:
- Right-click the choice2 node again to open the context menu, and select Add → Routing → When.
- In the Properties editor:
- Enter
/order/customer/country = 'Great Britain'
in the Expression field. - Select
xpath
from the Language drop-down menu. - Enter
when/gb
in the Id field.
- Right-click the when/gb node to open the context menu, and select Add → Transformation → SetHeader.
- In the Properties editor:
- Enter
Destination
in the Header Name field. - Enter
UK
in the Expression field. - Select constant from the Language drop-down menu.
- Enter
setHead_uk
in the Id field,
- Right-click the setHead_uk node to open the context menu, and select Add → Components → Log.
- In the Properties editor:
- Enter
Valid order - ship animals to UK customer
in the Message field. - Enter
log_uk
in the Id field.
- Right-click the log_uk node to open the context menu, and select Add → Components → File.
- In the Properties editor:
- Replace directoryName with
target/messages/GreatBritain
in the Uri field. - Enter
toUK
in the Id field.
Building and configuring the Germany branch of the second route
Route2
displayed on the canvas:
- Right-click the choice2 node again to open the context menu, and select Add → Routing → When.
- In the Properties editor:
- Enter
/order/customer/country = 'Germany'
in the Expression field. - Select
xpath
from the Language drop-down menu. - Enter
when/ger
in the Id field.
- Right-click the when/ger node to open the context menu, and select Add → Transformation → SetHeader.
- In the Properties editor:
- Enter
Destination
in the Header Name field. - Enter
Germany
in the Expression field. - Select constant from the Language drop-down menu.
- Enter
setHead_ger
in the Id field,
- Right-click the setHead_ger node to open the context menu, and select Add → Components → Log.
- In the Properties editor:
- Enter
Valid order - ship animals to Germany customer
in the Message field. - Enter
log_ger
in the Id field.
- Right-click the log_ger node to open the context menu, and select Add → Components → File.
- In the Properties editor:
- Replace directoryName with
target/messages/Germany
in the Uri field. - Enter
toGR
in the Id field.
Building and configuring the France branch of the second route
Route2
displayed on the canvas:
- Right-click the choice2 node again to open the context menu, and select Add → Routing → Otherwise.
- In the Properties editor:Enter
else/fr
in the Id field. - Right-click the else/fr node to open the context menu, and select Add → Transformation → SetHeader.
- In the Properties editor:
- Enter
Destination
in the Header Name field. - Enter
France
in the Expression field. - Select constant from the Language drop-down menu.
- Enter
setHead_fr
in the Id field,
- Right-click the setHead_fr node to open the context menu, and select Add → Components → Log.
- In the Properties editor:
- Enter
Valid order - ship animals to France customer
in the Message field. - Enter
log_fr
in the Id field.
- Right-click the log_fr node to open the context menu, and select Add → Components → File.
- In the Properties editor:
- Replace directoryName with
target/messages/France
in the Uri field. - Enter
toFR
in the Id field.
Saving the new routing context
- On the toolbar, select File → Save to save the routing context.The routes on the canvas should look like this:
Figure 5.1. Completed route1
Figure 5.2. Completed route2
- Click the Source tab at the bottom, left of the canvas to display the XML for the route.The
camelContext
element should look like that shown in Example 5.1.Example 5.1. XML for dual-route content-based router
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:camel="http://camel.apache.org/schema/blueprint" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd"> <camelContext trace="false" xmlns="http://camel.apache.org/schema/blueprint"> <route id="Route1"> <from uri="file:src/data?noop=true"/> <choice id="choice1"> <when id="when1"> <xpath>/order/orderline/quantity/text() > /order/orderline/maxAllowed/text()</xpath> <log message="quantity requested exceeds maximum allowed - contact customer" id="log1"/> <setHeader headerName="Destination" id="setHead1"> <constant>InvalidOrders</constant> </setHeader> <to uri="file:target/messages/invalidOrders" id="toInvalid"/> </when> <otherwise id="else2"> <log message="valid order - process" id="log2"/> <setHeader headerName="Destination" id="setHead2"> <constant>Dispatcher</constant> </setHeader> <to uri="direct:OrderFulfillment" id="toFulfill"/> </otherwise> </choice> </route> <route id="Route2"> <from uri="direct:OrderFulfillment"/> <choice id="choice2"> <when id="when/usa"> <xpath>/order/customer/country = 'USA'</xpath> <setHeader headerName="Destination" id="setHead_usa"> <constant>USA</constant> </setHeader> <log message="Valid order - ship animals to USA customer" id="log_usa"/> <to uri="file:target/messages/USA" id="toUS"/> </when> <when id="when/gb"> <xpath>/order/customer/country = 'Great Britain'</xpath> <setHeader headerName="Destination" id="setHead_uk"> <constant>UK</constant> </setHeader> <log message="Valid order - ship animals to UK customer" id="log_uk"/> <to uri="file:target/messages/GreatBritain" id="toUK"/> </when> <when id="when/ger"> <xpath>/order/customer/country = 'Germany'</xpath> <setHeader headerName="Destination" id="setHead_ger"> <constant>Germany</constant> </setHeader> <log message="Valid order - ship animals to Germany customer" id="log_ger"/> <to uri="file:target/messages/Germany" id="toGR"/> </when> <otherwise id="else/fr"> <setHeader headerName="Destination" id="setHead_fr"> <constant>France</constant> </setHeader> <log message="Valid order - ship animals to France customer" id="log_fr"/> <to uri="file:target/messages/France" id="toFR"/> </otherwise> </choice> </route> </camelContext> </blueprint>
Next steps
- Select
CBRroute
. - Right-click it to open the context menu, then select Refresh.
- Expand the folder
target/messages/
as shown in Figure 5.3. Themessage*.xml
files should be dispersed in your target destinations like this:Figure 5.3. Target message destinations in Project Explorer
NoteTo view message content, double-click a message to open it in the route editor's xml editor.
Further reading
Chapter 6. To Debug a Routing Context
Abstract
Goals
- In Source view, enter a unique ID for the camelContext element
- In Design view, set breakpoints on the nodes of interest in Route1
- Switch to Route2, and set breakpoints on the nodes of interest
- Invoke the Camel debugger
- Step through the route, examining route and message variables as they change
- Step through the route again, changing the value of message variables and observing the effects
Prerequisites
CBRroute
project you updated in Chapter 5, To Add Another Route to the CBR Routing Context.
camelContext6.xml
file to work through this tutorial (for details, see Chapter 1, Using the Fuse Tooling Resource Files).
Setting breakpoints
- If necessary, open your
CBRroute/src/main/resources/OSGI-INF/blueprint/camelContext.xml
in the route editor.By default, the route editor displays Route1 on the canvas. - Click the Source tab at the bottom of the route editor to switch to Source view.
- In the camelContext element, add
id="blueprintContext"
like this:<camelContext trace="false" id="blueprintContext" xmlns="http://camel.apache.org/schema/blueprint">
- Click File → Save to save your routing context file.
- Click the Design tab at the bottom of the route editor to switch to Design view.
- Select the choice1 node, and then click its icon to set an unconditional breakpoint.NoteIn the route editor, you can disable or delete a specific breakpoint by clicking the node's icon or its icon, respectively. You can delete all set breakpoints by right-clicking the canvas and selecting Delete all breakpoints.NoteIf you had not already set unique ID on the
camelContext
element and the nodes in your routing context, the Please Confirm dialog would have appeared now prompting you to let the tooling do it for you. - Repeat Step 6 to set an unconditional breakpoint on the following Route1 nodes:
- log1
- setHead1
- toInvalid
- log2
- setHead2
- toFulfill
- Click File → Save to save your routing context file.
- Click Routes → Route2 to open Route2 on the canvas.
- Repeat Step 6 to set an unconditional breakpoint on the following Route2 nodes:
- choice2
- setHead_usa
- log_usa
- toUSA
- setHead_uk
- log_uk
- toUK
- setHead_ger
- log_ger
- toGR
- setHead_fr
- log_fr
- toFR
- Click File → Save to save your routing context file.
Stepping through the CBRroute routing context
- Step over ( )—Jumps to the next node of execution in the routing context, regardless of breakpoints.
- Resume ( )—Jumps to the next active breakpoint in the routing context.
- In Project Explorer, expand the root node CBRroute to expose the
camelContext.xml
file in the Camel Contexts folder. - Right-click the
camelContext.xml
file to open its context menu, and then click Debug As... → Local Camel Context (without tests).NoteIf you select Local Camel Context, it will fail to run because you have not yet created a JUnit test for the CBRroute project. You will do that later in Chapter 8, To Test a Route with JUnit.The Camel debugger suspends execution at the first breakpoint it encounters and asks whether you want to open Debug perspective now. - Click Yes.NoteIf you click No, the confirmation pane appears several more times. After the third refusal, it disappears, and the Camel debugger resumes execution. To interact with the debugger at this point, you need to open the Debug perspective by clicking Window → Open Perspective → Debug.Debug perspective opens with the routing context suspended at
choice1 in Route1 [camelContext]
as shown in Debug view.NoteBreakpoints are held for a maximum of five minutes before the debugger automatically resumes, moving on to the next breakpoint or to the end of the routing context, whichever comes next. - In Variables view, expand the nodes to expose the variables and values available for each node.As you step through the routing context, the variables whose values have changed since the last breakpoint are highlighted in yellow. You may need to expand the nodes at each breakpoint to reveal variables that have changed.
- Click to step to the next breakpoint,
log2 in Route1 [camelContext]
. - Expand the nodes in Variables view to examine the variables that have changed since the last breakpoint at
choice1 in Route1 [camelContext]
. - Click to step to the next breakpoint,
setHead2 in Route1 [camelContext]
.Examine the variables that changed since the breakpoint atlog2 in Route1 [camelContext]
. - In Debug view, click
log2 in Route1 [camelContext]
to populate Variables view with the variable values from the breakpointlog2 in Route1 [camelContext]
for a quick comparison.In Debug view, you can switch between breakpoints within the same message flow to quickly compare and monitor changing variable values in Variables view.NoteMessage flows can vary in length. For messages that transit theinvalidOrders
branch ofRoute1
, the message flow is short. For messages that transit thevalidOrders
branch ofRoute1
, which continues on toRoute2
, the message flow is longer. - Continue stepping through the routing context. When one message completes the routing context and the next message enters it, the new message flow appears in Debug view, tagged with a new breadcrumb ID.In this case,
ID-janemurpheysmbp-home-55986-1423155548173-0-3
identifies the second message flow, corresponding tomessage2.xml
having entered the routing context. Breadcrumb IDs are incremented by 2.NoteExchange and Message IDs are identical and remain unchanged throughout a message's passage through the routing context. Their IDs are constructed from the message flow's breadcrumb ID, and incremented by 1. So, in the case ofmessage2.xml
, itsExchangeId
andMessageId
areID-janemurpheysmbp-home-55986-1423155548173-0-4
. - When
message3.xml
enters the breakpointchoice1 in Route1 [camelContext]
, examine the Processor variables. The values displayed are the metrics accumulated formessage1.xml
andmessage2.xml
, which previously transited the routing context.Timing metrics are in milliseconds. - Continue stepping each message through the routing context, examining variables and console output at each processing step. When
message6.xml
enters the breakpointtoGR in Route2 [camelContext]
, the debugger begins shutting down the breadcrumb threads. - In the Menu bar, click to terminate the Camel debugger. This will cause the Console to terminate, but you will have to manually clear the output.NoteWith a thread or endpoint selected under the Camel Context node in Debug view, you need to click twice—first to terminate the thread or endpoint and second to terminate the Camel Context, thus the session.
- In the Menu bar, right-click to open the context menu, and then select Close to close Debug perspective.Doing so automatically returns you to JBoss perspective.
- In Project Explorer, open the project's context menu, and select Refresh to refresh the display.NoteIf you terminated the session prematurely, before all messages transited the routing context, you might see, under the
CBRroute/CamelContexts/
folder, a file that looks like this:target/.CamelContextInDebug_xxxxxxxxxxxxxxxxxx_temp/camelContext.xml
. To remove it, open Project Explorer's context menu and click Refresh. - Expand the
CBRroute/target/messages/
* directories to check that the messages were delivered to their expected destinations: - Leave the routing context as is, with all previous breakpoints set and enabled.
Changing the value of a variable
- With message1 stopped at the first breakpoint,
choice1 in Route1 [camelContext.xml]
, add the variables NodeId and RouteId (in the Exchange category) and MessageBody and CamelFileName (in the Message category) to the watch list.For each of the four variables:- In Variables view, expand the appropriate category to expose the target variable:
- Right-click the variable (in this case, NodeId in the Exchange category) to open the context menu and select Watch:The Expressions tab opens, listing the variable you selected to watch:
- Repeat Step 1.b for each of the three remaining variables.
- Switch back to Variables view.
- Step message1 through the routing context until it reaches the fourth breakpoint,
toFulfill in Route1 [camelContext.xml]
. - In Variables view, expand the Message category.
- Repeat Step 1.b to add the variable Destination to the watch list.Expressions view should now contain these variables:NoteThe pane below the list of variables displays the value of the selected variable.NoteExpressions view retains all variables you add to the list until you explicitly remove them.
- Step message1 through the rest of the routing context.
- Stop message2 at
choice1 in Route1 [camelContext.xml]
. - In Variables view, expand the Message category to expose the MessageBody variable.
- Right-click MessageBody to open its context menu, and select Change Value....
- Change the value of quantity from
3
to2
.This changes the in-memory value only. - Click OK.
- Switch to Expressions view, and select the MessageBody variable.The pane below the list of variables displays the entire body of message2, making it easy to check the current value of order items:NoteCreating a watch list makes it easy for you to quickly check the current value of multiple variables of interest.
- Click to step to the next breakpoint.Instead of following the branch leading to
InvalidOrders
, message2 now follows the branch leading totoFulfill
. - Step message2 through the routing context, checking Debug view, Variables view, and Console output at each step.
- Stop message3 at
choice1 in Route1 [camelContext.xml]
. - Switch to Breakpoints view, and disable all breakpoints (12) between
choice1
andtoFulfill
: - Switch back to Variables view.
- Click to step to the next breakpoint.The debugger jumps to
toFulFill in Route1 [camelContext.xml]
. - Click again to step to the next breakpoint.The debugger jumps to
toUK in Route2 [camelContext.xml]
. - Switch to Breakpoints view, and re-enable all disabled breakpoints.
- Switch back to Variables view.
- Click to step to the next breakpoint, and stop message4 at
choice1 in Route1 [camelContext.xml]
. - Right-click MessageBody to open its context menu, and select Change Value....
- Change the value of quantity from
5
to4
. - Click OK.
- Switch to Expressions view, and select the MessageBody variable to check the value of quantity in the body of message4.
- Click repeatedly to quickly step message5 and message6 through the routing context.
- In the Menu bar, click to terminate the Camel debugger.This will also cause the Console to terminate, but you will have to click its button to clear the output.
- In the Menu bar, right-click to open the context menu, and then select Close to close Debug perspective.Doing so automatically returns you to JBoss perspective.
- In Project Explorer, open the project's context menu, and select Refresh to refresh the display.
- Expand the
CBRroute/target/messages/
* directories to check whether the messages were delivered as expected:You should see that no messages were sent to theinvalidOrders
folder. Instead,message2.xml
should appear in theUSA
folder, andmessage4.xml
should appear theGreatBritain
folder.
Next steps
Chapter 7. To Trace a Message Through a Route
Abstract
Goals
- run the CBRroute in the Fuse Integration perspective
- enable tracing on the CBRroute
- drop messages onto the CBRroute and track them through all route nodes
Prerequisites
CBRroute
project you updated in Chapter 5, To Add Another Route to the CBR Routing Context.
camelContext6.xml
file to work through this tutorial (for details, see Chapter 1, Using the Fuse Tooling Resource Files).
Accessing Fuse Integration perspective
- Select Window → Open Perspective → Other... → Fuse Integration to open the Fuse Integration perspective, as shown in Figure 7.1.NoteYou can use the Open Perspective icon ( ) in the perspectives tab to access the list of available perspectives.
Figure 7.1. Fuse Integration perspective
NoteTo make it easy to access a Camel Context.xml
file, especially when a project consists of multiple contexts, the tooling lists them in theCamel Contexts
folder, beneath the project's root folder in Project Explorer; for example: - Drag the Diagram View tab and the Shell tab, located to the left of the JMX Navigator tab, and drop them to the right of the JMX Navigator tab, as shown in Figure 7.2.
Figure 7.2. Fuse Integration perspective rearranged
This layout will provide more space for Diagram View to display the route's nodes in a graphical representation, enabling you to visually trace the path that messages take in traversing the routing context.
Starting message tracing
- In Project Explorer, expand the
CBRroute
project to expose thesrc/main/resources/OSGI-INF/blueprint/camelContext.xml
file. - Select Run As → Local Camel Context (without tests) from the
camelContext.xml
file's context menu. - In JMX Navigator, expand Local Processes.
- Double click
Local Camel Context[Id][Disconnected]
to connect to it and expand the elements of your route, as shown in Figure 7.3, “Route elements in JMX Navigator”.Figure 7.3. Route elements in JMX Navigator
- Right-click the blueprintContext node to open the context menu, and select Start Tracing.The tooling displays a graphical representation of your route in Diagram View, as shown in Figure 7.4.
Figure 7.4. Routes' graphical representation
Dropping messages on the running CBRroute project
- In Project Explorer, expand
CBRroute/src/data
, so you can access the message files (message1.xml
throughmessage6.xml
), as shown in Figure 7.5, “Message files in CBRroute project”.Figure 7.5. Message files in CBRroute project
- Drag
message1.xml
and drop it on theblueprintContext>Endpoints>file>src/data?noop=true
node in JMX Navigator, as shown in Figure 7.6.Figure 7.6. Local Camel Context tree expanded to input source node
As the message traverses the route, the tooling traces and records its passage at each step. To update Diagram View with the new message count, you need to click theblueprintContext
node in JMX Navigator.NoteTheLocal Camel Context[xxx]
tree collapses to theblueprintContext
node after you drop the next message on the input src node. You need not re-expand it. When dragging the other messages, hover over each node in the tree to expose the next node, until you reach thesrc/data?noop=true
node. Then drop the message on it. This method prevents the tooling from redrawing the graphical representation in Diagram View.
Initializing and configuring Messages View
- Switch from Console to Messages View.
- Click the
blueprintContext
node in JMX Navigator to initialize Messages View withmessage1.xml
's details.NoteYou can control columnar layout in all of the tooling's tables. Use the drag method to temporarily rearrange tabular format. For example, drag a column's border rule to expand or contract its width. To hide a column, totally contract its borders. Drag the column header to relocate a column within the table. For your arrangement to persist, you must use the View Menu → Configure Columns... method instead. - In Messages View, click the icon on the panel's menu bar, and select Configure Columns... to open the Configure Columns wizard, as shown in Figure 7.7.
Figure 7.7. Configure Columns defaults
NoteNotice that the message header,Destination
, which you set for the messages in your routing context, appears in the list.You can include or exclude items from Messages View by selecting or deselecting them. You can rearrange the columnar order in which items appear in Messages View by highlighting individual, selected items and moving them up or down in the list. - In the Configure Columns wizard, select and order the items as shown in Figure 7.8.
Figure 7.8. Configure Columns set
These items and their order will persist in Messages View until you change them again.
Arranging Diagram View
Stepping through message traces
- In Messages View, click the (Refresh button) on top, right of the panel's menu bar to populate the view with
message1.xml
's message traces.Each time you drop a message on the inputsrc
node in JMX Navigator, you need to refresh Messages View to populate it with the message traces. - Click one of the message traces to see more details about it in Properties view, as shown in Figure 7.9.
Figure 7.9. Message trace selected
The tooling displays the details about a message trace (including message headers when they are set) in the top half of the Properties panel and the contents of the message instance in the bottom half of the Properties panel. So, if your application sets headers at any step within a route, you can check the Message Details to see whether they were set as expected.You can step through the message instances by highlighting each one to see how a particular message traversed the route and whether it was processed as expected at each step in the route.In Diagram View, the associated step in the route is highlighted, as shown in Figure 7.10.Figure 7.10. Diagram View: message trace node
Finishing up
- Drag
message2.xml
and drop it on theblueprintContext>Endpoints>file>src/data?noop=true
node in JMX Navigator.Hover over each node in the tree until you expose thesrc/data?noop=true
node, then dropmessage2.xml
on it. - Switch from Console to Messages View.
- In Messages View, click the (Refresh button) on top, right of the panel's menu bar to populate the view with
message2.xml
's message traces.NoteAs shown in Figure 7.11, the tooling draws the route in Diagram View, tagging paths exiting a processing step with timing and performance metrics (in milliseconds). Only the metric Total exchanges is displayed in the diagram.Figure 7.11. Fuse Integration perspective's message tracing components
Hovering over the displayed metrics reveals additional metrics about message flow, as shown in Figure 7.12.Figure 7.12. Additional message metrics
- mean time the step took to process a message
- maximum time the step took to process a message
- minimum time the step took to process a message
- When done:
- In JMX Navigator, right-click blueprintContext and select Stop Tracing Context from the context menu.
- Open the Console and click the button in the upper right of the panel to stop the Console. Then click the button to clear console output.
Next steps
Chapter 8. To Test a Route with JUnit
Abstract
Overview
Goals
- delete the existing JUnit test case
- generate a new JUnit test case for the CBRroute project
- modify the newly generated JUnit test case
- modify the CBRroute project's
pom.xml
file - run the CBRroute with the New JUnit test case
- observe the output
Prerequisites
camelContext6.xml
file to work through this tutorial (for details, see Chapter 1, Using the Fuse Tooling Resource Files).
/src/data/
directory and /target/messages/
subdirectories in Project Explorer. Trace-generated messages begin with the ID-
prefix. For example, Figure 8.1, “Trace-generated messages” shows six trace-generated messages:
Figure 8.1. Trace-generated messages
Deleting the existing test case
- In Project Explorer, expand
src/test/java
to expose theCamelContextXmlTest
file, as shown in Figure 8.2.Figure 8.2. CamelContextXmlTest.java file location
- Right-click it to open the context menu, and select Delete.A dialog box opens asking you to confirm deletion of the test case file.
- Click OK.
- Verify that the existing test case has been deleted by right-clicking CBRroute and selecting Refresh.The
src/test/java/tutorial.cbr.route
directory should be empty.
Creating the new test case
- In Project Explorer, select
src/test/java
. - Right-click it to open the context menu, and then select New → Camel Test Case to open the New Camel JUnit Test Case wizard, as shown in Figure 8.3.
Figure 8.3. New Camel JUnit Test Case wizard
- Make sure the Source folder field contains
CBRroute/src/test/java
.NoteIf needed, you can click to find the proper folder. - The Package field defaults to
tutorial.cbr.route
. To include the test case in a different package, enter the name of the package. - In the Camel XML file under test field, enter
src/main/resources/OSGI-INF/blueprint/camelContext.xml
, or use to open a file explorer, configured to screen for XML files, to locate the file.NoteThe Name field defaults to CamelContextXmlTest for the name of the test file. Figure 8.4. Test Endpoints page
- By default, all endpoints are selected and will be included in the test case. Leave them selected for this tutorial.NoteYou can select or deselect all endpoints by clicking the Select All or Deselect All button, or you can select and deselect individual endpoints by clicking the check box next to each.
- Click Finish.NoteIf prompted, add JUnit to the build path.
src/test/java
. The class implementing the test case opens in the tooling's Java editor:
package tutorial.cbr.route; import org.apache.camel.EndpointInject; import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.blueprint.CamelBlueprintTestSupport; import org.junit.Test; public class CamelContextXmlTest extends CamelBlueprintTestSupport { // TODO Create test message bodies that work for the route(s) being tested // Expected message bodies protected Object[] expectedBodies = { "<something id='1'>expectedBody1</something>", "<something id='2'>expectedBody2</something>"; // Templates to send to input endpoints @Produce(uri = "file:src/data?noop=true") protected ProducerTemplate inputEndpoint; // Mock endpoints used to consume messages from the output endpoints and then perform assertions @EndpointInject(uri = "mock:output") protected MockEndpoint outputEndpoint; @EndpointInject(uri = "mock:output2") protected MockEndpoint output2Endpoint; @EndpointInject(uri = "mock:output3") protected MockEndpoint output3Endpoint; @EndpointInject(uri = "mock:output4") protected MockEndpoint output4Endpoint; @EndpointInject(uri = "mock:output5") protected MockEndpoint output5Endpoint; @Test public void testCamelRoute() throws Exception { // Create routes from the output endpoints to our mock endpoints so we can assert expectations context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("file:target/messages/Germany").to(output4Endpoint); from("file:target/messages/GreatBritain").to(output3Endpoint); from("file:target/messages/USA").to(output2Endpoint); from("file:target/messages/France").to(output5Endpoint); from("file:target/messages/invalidOrders").to(outputEndpoint); } }); // Define some expectations // TODO Ensure expectations make sense for the route(s) we're testing output4Endpoint.expectedBodiesReceivedInAnyOrder(expectedBodies); // Send some messages to input endpoints for (Object expectedBody : expectedBodies) { inputEndpoint.sendBody(expectedBody); } // Validate our expectations assertMockEndpointsSatisfied(); } @Override protected String getBlueprintDescriptor() { return "OSGI-INF/blueprint/camelContext.xml"; } }
pom.xml
, as described in the section called “Modifying the CamelContextXmlTest file ” and the section called “Modifying the pom.xml file”.
Modifying the CamelContextXmlTest file
CamelContextXmlTest.java
file to:
- import several classes that support required file functions
- create variables for holding the content of the various source
.xml
files - read the content of the source
.xml
files - define appropriate expectations
- In Project Explorer, expand the CBRroute project to expose the
CamelContextXmlTest
item. - Double-click
CamelContextXmlTest
to open the file in the route editor. - In the route editor, click the expand button next to
import org.apache.camel.EndpointInject;
to expand the list. - Add the three lines shown here:
- Scroll down to the lines that follow directly after
// Expected message bodies
. - Replace those lines—
protected Object[] expectedBodies={ ...... expectedBody2</something>"};
— with theprotected String body#;
lines shown here: - Scroll down to the line
public void testcamelRoute() throws Exception {
, and insert directly after it the linesbody# = FileUtils.readFileToString(new File("src/data/message#.xml"));
shown here: - Scroll down to the lines that follow directly after
// TODO Ensure expectations make sense for the route(s) we're testing
. - Replace the block of code that begins with
output4Endpoint.expectedBodiesReceivedInAnyOrder(expectedBodies);
and ends with ...inputEndpoint.sendBody(expectedBody); }
with the lines shown here:Leave the remaining code as is. - Save the file.
- Check that your updated
CamelContextXmlTest.java
file has the required modifications. It should look something like this:package tutorial.cbr.route; import org.apache.camel.EndpointInject; import org.apache.camel.Produce; import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.mock.MockEndpoint; import org.apache.camel.test.blueprint.CamelBlueprintTestSupport; import org.apache.commons.io.FileUtils; import org.junit.Test; import java.io.File; import java.util.Scanner; public class CamelContextXmlTest extends CamelBlueprintTestSupport { // TODO Create test message bodies that work for the route(s) being tested // Expected message bodies // To assert that everything works as it should, read the content of created xml files. protected String body1; protected String body2; protected String body3; protected String body4; protected String body5; protected String body6; // Templates to send to input endpoints @Produce(uri = "file:src/data?noop=true") protected ProducerTemplate inputEndpoint; // Mock endpoints used to consume messages from the output // endpoints and then perform assertions @EndpointInject(uri = "mock:output") protected MockEndpoint outputEndpoint; @EndpointInject(uri = "mock:output2") protected MockEndpoint output2Endpoint; @EndpointInject(uri = "mock:output3") protected MockEndpoint output3Endpoint; @EndpointInject(uri = "mock:output4") protected MockEndpoint output4Endpoint; @EndpointInject(uri = "mock:output5") protected MockEndpoint output5Endpoint; @Test public void testCamelRoute() throws Exception { // Easy way of reading content of xml files to a String object. // But you must add dependency on commons-io project to pom.xml body1 = FileUtils.readFileToString(new File("src/data/message1.xml")); body3 = FileUtils.readFileToString(new File("src/data/message3.xml")); body5 = FileUtils.readFileToString(new File("src/data/message5.xml")); body6 = FileUtils.readFileToString(new File("src/data/message6.xml")); // Invalid orders. body2 = FileUtils.readFileToString(new File("src/data/message2.xml")); body4 = FileUtils.readFileToString(new File("src/data/message4.xml")); // Create routes from the output endpoints to our mock endpoints // so we can assert expectations context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("file:target/messages/Germany").to(output4Endpoint); from("file:target/messages/GreatBritain").to(output3Endpoint); from("file:target/messages/USA").to(output2Endpoint); from("file:target/messages/France").to(output5Endpoint); from("file:target/messages/invalidOrders").to(outputEndpoint); } }); // Define some expectations // TODO Ensure expectations make sense for the route(s) we're testing // Invalid orders outputEndpoint.expectedBodiesReceived(body2, body4); // For each country one order output2Endpoint.expectedBodiesReceived(body1); output3Endpoint.expectedBodiesReceived(body3); output4Endpoint.expectedBodiesReceived(body6); output5Endpoint.expectedBodiesReceived(body5); // Validate our expectations assertMockEndpointsSatisfied(); } @Override protected String getBlueprintDescriptor() { return "OSGI-INF/blueprint/camelContext.xml"; } }
Modifying the pom.xml file
pom.xml
file.
- In Project Explorer, double-click
pom.xml
, located below thetarget
folder, to open the file in the route editor. - Click the pom.xml tab at the bottom of the page to open the file for editing.
- Add these lines to the end of the
<dependencies>
section:<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> <scope>test</scope> </dependency>
- Save the file.The contents of the entire
pom.xml
file should look like this:<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>tutorial</groupId> <artifactId>cbr-route</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>bundle</packaging> <name>A Camel Blueprint Route</name> <url>http://www.myorganization.org</url> <properties> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>2.15.0</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-blueprint</artifactId> <version>2.15.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-test-blueprint</artifactId> <version>2.15.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.camel<</groupId> <artifactId>camel-infinispan</artifactId> <version>2.15.0</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jgroups</artifactId> <version>2.15.0</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-test</artifactId> <version>2.15.0</version> <scope>test</scope> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> <scope>test</scope> </dependency> </dependencies> <build> <defaultGoal>install</defaultGoal> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>2.3.7</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>cbr-route</Bundle-SymbolicName> <Private-Package>tutorial.cbr.route.*</Private-Package> <Import-Package>*</Import-Package> </instructions> </configuration> </plugin> <plugin> <groupId>org.apache.camel</groupId> <artifactId>camel-maven-plugin</artifactId> <version>2.15.0</version> <configuration> <useBlueprint>true</useBlueprint> </configuration> </plugin> </plugins> </build> </project>
Running the JUnit test
- Switch to JBoss perspective to free up more workspace.
- Select the project root,
CBRroute
, in the Project Explorer. - Open the context menu.
- Select Run As → JUnit Test.NoteBy default, JUnit view opens in the sidebar. (To provide a better view, drag it to the bottom, right panel that displays the Console, Servers, and Properties tabs.)
- If the test runs successfully, you'll see something like this:
Figure 8.5. Successful JUnit run
If the test fails, you'll see something like this:Figure 8.6. Failed JUnit run
NoteJUnit will fail if your execution environment is not set to Java SE 7 or above. The message bar at the top of the JUnit tab will display an error message indicating that it cannot find the correct SDK.To resolve the issue, open the project's context menu, and select Run As → Run Configurations → JRE tab . Click the Environments button next to the Execution environment: field to locate and select a Java SE 7 environment. - Examine the output and take action to resolve any test failures.To see more of the errors displayed in the JUnit panel, click on the panel's menu bar to maximize the view. You can also check the surefire reports in the
surefire-reports
tab in Project Explorer, as shown in Figure 8.7.Figure 8.7. JUnit surefire reports
Before you run the JUnit test case again, delete any JUnit-generated test messages from the CBRroute project's/src/data
folder in Project Explorer (see Figure 8.1, “Trace-generated messages”).
Further reading
- see JUnit
Chapter 9. To Publish a Fuse Project to Red Hat JBoss Fuse
Abstract
Goals
- define a Red Hat JBoss Fuse server
- configure the publishing options
- start up the Red Hat JBoss Fuse server and publish the CBRroute project
- connect to the Red Hat JBoss Fuse server
- verify whether the CBRroute project's bundle was successfully built and published
- uninstall the CBRroute project
Prerequisites
- access to a Red Hat JBoss Fuse 6.2 instance
- the CBRroute project you updated in Chapter 8, To Test a Route with JUnit
Defining a Red Hat JBoss Fuse Server
- Open Fuse Integration perspective.
- Click the Servers tab in the lower, right panel to open the Servers view.
- Click the link No servers are available. Click this link to create a new server... to open the Define a New Server page.NoteTo define a new server when one is already defined, right-click inside Servers view to open the context menu, and then select New → Server.
- Expand the
JBoss Fuse
node to expose the available server options: - Click
JBoss Fuse 6.2 Server
. - Accept the defaults for Server's host name (localhost) and Server name (JBoss Fuse 6.2 Runtime Server), and then click Next to open the JBoss Fuse Runtime page:NoteIf you do not have JBoss Fuse 6.2 already installed, you can download it now using the Download and install runtime... link.NoteIf you have already defined a JBoss Fuse 6.2 server, the tooling skips this page, and instead displays the configuration details page shown in Step 11.
- Accept the default for Name (JBoss Fuse 6.2 Runtime).
- In Home Directory, enter the path where the JBoss Fuse 6.2 installation is located, or click Browse to find and select it.
- Select the runtime JRE from the drop-down menu next to Execution Environment.Select either JavaSE-1.7 or JavaSE-1.8. If neither appears as an option, click the Environments... button and select either version from the list.NoteThe JBoss Fuse 6.2 server requires Java 7 or Java 8. To select either version for the Execution Environment, you must have previously installed it.
- Leave the Alternate JRE option as is.
- Click Next to save the runtime definition for JBoss Fuse 6.2 Server and open the JBoss Fuse server configuration details page:
- Accept the default for SSH Port (8101).The runtime uses the SSH port to connect to the server's Karaf shell. If this default is incorrect, you can discover the correct port number by looking in the Red Hat JBoss Fuse installDir
/etc/org.apache.karaf.shell.cfg
file. - In User Name, enter the name used to log into the server.This is a user name stored in the Red Hat JBoss Fuse installDir
/etc/users.properties
file.NoteIf the default user has been activated (uncommented) in the/etc/users.properties
file, the tooling autofills User Name and Password with the default user's name and password, as shown in Step 11.If one has not been set, you can either add one to that file using the formatuser=password,role
(for example,joe=secret,Administrator
), or you can set one using the karafjaas
command set:jaas:realms
—to list the realmsjaas:manage --index 1
—to edit the first (server) realmjaas:useradd <username> <password>
—to add a user and associated passwordjaas:roleadd <username> Administrator
—to specify the new user's rolejaas:update
—to update the realm with the new user information
If a jaas realm has already been selected for the server, you can discover the user name by issuing the commandJBossFuse:karaf@root>
jaas:users
. - In Password:, enter the password required for User name to log into the server.This is the password set either in Red Hat JBoss Fuse's installDir
/etc/users.properties
file or by the karafjaas
commands. - Click Next to open the Add and Remove resources page:
- Select CBRroute, and click Add> to assign it to the JBoss Fuse server.
- Click Finish.
JBoss Fuse 6.2 Runtime Server [stopped]
appears in Servers view. - In Servers view, expand
JBoss Fuse 6.2 Runtime Server [stopped]
:The CBRroute module and JMX[Disconnected] appear as nodes underJBoss Fuse 6.2 Runtime Server [stopped]
entry.
Configuring the publishing options
- Automatically, immediately upon saving changes made to the project
- Automatically, at configured intervals after you have changed and saved the project
- Manually, when you select a publish operation
- In Servers view, double-click the
JBoss Fuse 6.2 Runtime Server [stopped]
entry to open the server's editor: - On the server editor's Overview page, expand the Publishing section to expose the options.Make sure the option Automatically publish when resources change is enabled.Change the value of Publishing interval to speed up or delay publishing the project when changes have been made.
- disable the If server started, publish changes immediately option on the server's Add and Remove page
- enable the Never publish automatically option on the server editor's Overview page
Starting up Red Hat JBoss Fuse server
JBoss Fuse 6.2 Runtime Server
, the publish mechanism automatically publishes the CBRroute to the server.
- In Servers view, select
JBoss Fuse 6.2 Runtime Server
and click to start it.ImportantA warning that the host identification has changed may appear. Click yes to replace the key ONLY if the JBoss Fuse 6.2 server runtime is installed on the same machine where Red Hat JBoss Fuse Tooling is running! Otherwise click no and contact your system administrator. - Wait a few seconds for JBoss Fuse 6.2 Server to start up. When it does:
- Shell view displays the JBoss Fuse splash screen:
- Servers view displays:
JBoss Fuse 6.2 Runtime Server [Started, Synchronized]
NoteFor a server, synchronized means that all modules published on the server are identical to their local counterparts.CBRroute [Started, Synchronized]
NoteFor a module, synchronized means that the published module is identical to its local counterpart. Because automatic publishing is enabled, changes made to the CBRroute project are published in seconds (according to the value of the Publishing interval).JMX[Disconnected]
- JMX Navigator displays
JBoss Fuse 6.2 Runtime Server[Disconnected]
:
Connecting to the JBoss Fuse 6.2 runtime server
JBoss Fuse 6.2 Runtime Server
, you can see the published elements of your CBRroute project and interact with them.
- In Servers view, double-click JMX[Disconnected] to connect to the runtime server.ImportantIf the CBRroute project contains a failed JUnit test, the published module will not be started nor its bundle installed. The published module will appear in Servers view under
JBoss Fuse 6.2 Runtime Server[Started, Synchronized]
asCBRroute[Synchronized]
.You need to correct the JUnit test case (see the section called “Modifying the CamelContextXmlTest file ” for details) so that it runs on the CBRroute without errors, and save the updated test file. Saving the test file will trigger immediate publishing when that option is enabled. The module should then be started and its bundle installed. - Expand the Camel node in JMX Navigator to expose the elements of the CBRroute.You can interact with the CBRroute routing context using either Servers view or JMX Navigator, but JMX Navigator provides more room to expand the routing context's nodes, making it easier for you to access them.NoteOnce the
blueprintCamel
node appears in JMX Navigator under Server Connections (or in Servers view under JMX[Connected]), you can start tracing on it, as described in Chapter 7, To Trace a Message Through a Route. - Click the Bundles node to populate Properties view with the list of bundles installed on the
JBoss Fuse 6.2 Runtime Server
.Start typing cbr-route in Properties view's Search tool to quickly determine whether your project'scbr-route
bundle is included in the list. Note that it is the last bundle in the list, identified by its Symbolic Name,cbr-route
, which is the Artifact Id you gave it in Step 6 when you created the CBRroute project.NoteAlternatively, you can issue the list command in Shell view to see a generated list of installed bundles.
Uninstalling the CBRroute project
- In Servers view, right-click
JBoss Fuse 6.2 Runtime Server
to open the context menu. - Select Add and Remove:
- In the Configured column, select CBRroute, and then click Remove to move the CBRroute resource to the Available column.
- Click Finish.
- In Servers view, right-click JMX[Connected] to open the context menu, and then click Refresh.The Camel tree under JMX[Connected] disappears.NoteIn JMX Navigator, the Camel tree under Server Connections > JBoss Fuse 6.2 Runtime Server[Connected] also disappears.
- With the Bundles page displayed, start typing cbr-route in Properties view's Search tool to verify that the bundle has been removed.
Legal Notice
Trademark Disclaimer