Tooling Tutorials

Red Hat JBoss Fuse 6.3

Tooling Tutorials

Red Hat JBoss Fuse Documentation Team

Abstract

This guide contains a number of simple tutorials that demonstrate how to use the tooling provided by Red Hat JBoss Fuse Tooling to develop and test applications.

Chapter 1. Using the Fuse Tooling Resource Files

Experienced users may want to focus only on the tutorials that demonstrate the tooling’s new features. To do so, you need to download and install the requisite resource files. The prefabricated message files are used by all tutorials, but the prefabricated routing context files are specific to particular tutorials. With the exception of Chapter 2, To Create a New Route, using these prefabricated resource files enables you to complete the remaining tutorials in any order. Without them, you must complete each tutorial sequentially, as the code generated by one tutorial is the starting point for the next tutorial.

Prerequisites

You must complete Chapter 2, To Create a New Route, to create the project, the new routing context, and the folder that will hold the test messages. The code generated by this tutorial is used by Chapter 3, To Run a Route and by Chapter 4, To Add a Content-Based Router.

Downloading the resource files

Click here to download the jbds-10.1.zip file. Move it to a convenient location external to the CBRroute project’s workspace, and unzip it. It contains two folders:

  • Messages

    This folder contains six prefabricated message files named message1.xml, message2.xml,…​, message6.xml used in all of the tutorials. In Chapter 2, To Create a New Route, you will create the directory in which to store these message files, and also learn how to create them.

  • blueprintContexts

    This folder contains two prefabricated routing context files named blueprint5.xml, and blueprint6.xml, which can be used in one or more of the tutorials:

    Use prefabricated routing context file:To complete tutorials:

    blueprint5.xml

    To Add Another Route to the CBR Routing Context

    blueprint6.xml

    To Debug a Routing Context

    To Trace a Message Through a Route

    To Test a Route with JUnit

    To Publish a Fuse Project to Red Hat JBoss Fuse

    Note

    blueprint5.xml is the routing context file generated by completing Chapter 4, To Add a Content-Based Router.

Installing the prefabricated routing context files

To install the blueprint#.xml files:

  1. Delete the existing blueprint.xml file from the CBRroute/src/main/resources/OSGI-INF/blueprint/ folder.
  2. Copy the blueprint#.xml file that corresponds to the tutorial that you want to complete to the vacated CBRroute/src/main/resources/OSGI-INF/blueprint/ folder.
  3. Rename the blueprint#.xml file blueprint.xml.
  4. Follow the instructions for completing the target tutorial.

Chapter 2. To Create a New Route

This tutorial walks you through the process of creating a Fuse Integration project, adding a route to it, and adding two endpoints to the route. It assumes that you have already set up your workspace and that Red Hat JBoss Fuse Tooling is running inside Red Hat JBoss Developer Studio.

Goals

In this tutorial you will:

  • Create a Fuse Integration project
  • Create a new routing context
  • Create a route

    • Add file 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

  • JBoss Developer Studio 11.2 installed
  • Red Hat JBoss Fuse Tooling 10.2 installed in JBoss Developer Studio 11.2
  • In Developer Studio, select menu:Window[ > > Preferences > > Fuse Tooling > > Editor > ] and confirm selection of this option: If enabled the ID values will be used for labels if existing. This ensures that the label of the patterns and components that you place on the canvas will be the same as the labels shown in these tutorials.

When you start Developer Studio for the first time, it opens in the JBoss perspective:

JBoss View on JBDS startup
Note

You can start this tutorial in the JBoss perspective or in the Fuse Integration perspective. If you start it in the JBoss perspective, the tooling will ask to switch you to the Fuse Integration perspective at the appropriate point in the tutorial.

Creating the Fuse Integration project

To create a Fuse Integration project:

  1. From the menu bar, select menu:File[ > > New > > Other > > JBoss Fuse > > Fuse Integration Project > ] and click Next to open the New Fuse Integration Project wizard:

    newFuseProjectTut
  2. In the Project Name field, enter CBRroute.
  3. Leave the Use default workspace location option as is.
  4. Click Next to open the Select a Target Runtime page:

    Select Target
  5. Accept No Runtime selected for Target Runtime, and 2.18.1.redhat-000015 for Camel Version.

    Note

    You will add the runtime later in the tutorial Chapter 9, To Publish a Fuse Project to JBoss Fuse.

  6. Click Next to open the Advanced Project Setup page:

    Advanced Project Setup
  7. Leave the Start with an empty project and Blueprint DSL options selected.
  8. Click Finish.

    Fuse Tooling starts downloading from the Maven repository all of the files it needs to build the project, and then adds the new project to Project Explorer.

    If you are not in the Fuse Integration perspective, the tooling asks whether you want to switch to it now:

    tutSwitchToFIP
  9. Click Yes to open the new CBRroute project in the Fuse Integration perspective:

    tutEmptyProjectOpen

    The new CBRroute project contains everything needed to create and run routes. As shown in Figure 2.1, “Generated project files”, the files generated for CBRroute 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.1. Generated project files

      generated blueprint.xml and pom.xml files
      Note

      Notice that the pom.xml entry in Project Explorer is decorated wth a warning symbol.

      You can safely ignore this warning or eliminate it by opening the pom.xml file in the tooling’s XML editor, and delete the <version> element from each dependency: camel-core, camel-blueprint, and camel-test-blueprint. Save the pom.xml file.

Creating the route

To create the route:

  1. Click the Design tab at the bottom, left of the canvas to return to the graphic display of the route.
  2. Drag a File component ( File icon ) from the Palette's Components drawer to the canvas, and drop it in the Route_route1 container node.

    The File component changes to a From _from1 node inside the Route_route1 container node.

  3. On the canvas, select the From _from1 node.

    The Properties view, located below the canvas, displays the node’s property fields for editing.

  4. In the Properties view, click the Advanced tab:

    FileSysCompProps1Tut

    You need to create a folder for the project’s source data and enter that folder’s name in the Directory Name field.

    1. In Project Explorer, right-click CBRroute/src/ to open the context menu.
    2. Select menu:[ > New > > Folder > ] to open the New Folder wizard:

      TutNewFolderData
    3. 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.
    4. In the Folder name field, enter data, and then click Finish.

      The new data folder appears in Project Explorer, under the src folder:

      TutDataDirCreated
  5. In the Properties view, return to the From _from1 node’s Advanced tab.
  6. In the Directory Name field, enter src/data:

    FileSystemCompPropsTut

    The path src/data is relative to the project’s directory.

  7. On the Consumer tab, 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.

  8. Select the Details tab to open the file node’s Details page.

    The tooling automatically populates the Uri field with the Directory Name and Noop properties you configured on the Advanced tab. It also populates the Id field with an autogenerated ID (_from1):

    FileSystemCompPropsTut2
  9. Leave the autogenerated Id as is.
  10. Drag another File component from the Palette's Components drawer and drop it in the Route_route1 container node.

    The File component changes to a To _to1 node inside the Route_route1 container node.

  11. On the canvas, select the To _to1 node.

    The Properties view, located below the canvas, displays the node’s property fields for editing.

  12. On the Details tab, enter file:target/messages/others in the Uri field, and _Others in the Id field:

    FilesysTargetCompPropsTut
    Note

    The tooling will create the target/messages/others folder at runtime.

  13. In the Route_route1 container, select the From _from1 node and drag it’s connector arrow ( connector arrow icon ) over the To_Others node, then release it:

    CompletedRoute1
    Note

    The two file nodes are connected and aligned on the canvas according to the route editor’s layout direction preference setting. The choices are Right and Down (default).

    Note

    If you do not connect the nodes before you close the project, the tooling automatically connects them when you reopen it.

  14. Select FileSave to save the route.
  15. Click the Source tab at bottom, left of the canvas to display the XML for the route. The camelContext element will look like Example 2.1, “XML for CBRroute”:

    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:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
        https://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 id="_context1" xmlns="http://camel.apache.org/schema/blueprint">
            <route id="_route1">
                <from id="_from1" uri="file:src/data?noop=true"/>
                <to id="_Others" uri="file:target/messages/others"/>
            </route>
        </camelContext>
    </blueprint>

Creating test messages

Before you can run your route, you need to create test messages to send through it.

  1. In Project Explorer, right-click CBRroute to open the context menu.
  2. Click menu:New[ > > Fuse Message > ] to open the New File wizard:

    FuseMsgWizTut
  3. 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.
  4. In the File Name: field, enter message1.xml.
  5. Click Finish to open the test message, message1.xml in the Design tab:

    FuseMsgNewTut
  6. Click the Source tab at the bottom of the canvas:

    FuseMsgNewTut2
  7. In the Source tab, 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>
    Note

    You can safely ignore the Warning icon on the last line of the newly created message1.xml file, which advises you that there are no grammar constraints (DTD or XML Schema) referenced by the document.

  8. Save the file, and close it.
  9. If you haven’t already done so, download the prefabricated test message files (see Chapter 1, Using the Fuse Tooling Resource Files for instructions). Copy message2.xml through message6.xml into the newly created CBRroute/src/data folder. You will use all six test messages in the remaining Fuse Tooling tutorials.

    Table 2.1, “Preconstructed test messages” shows the contents of each remaining prefabricated 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

After you have created and designed your route, you can run it by deploying it into your local Apache Camel runtime, as described in Chapter 3, To Run a Route.

Further reading

To learn more about using the editor, see the Editing a routing context in the route editor section in "Tooling User Guide".

Chapter 3. To Run a Route

This tutorial walks you through the process of running a route.

Goals

In this tutorial you will:

  • Run a route as a Local Camel Context (without tests)
  • Send messages through the route
  • Examine the messages received by the endpoints

Prerequisites

To complete this tutorial you will need the CBRroute project created in Chapter 2, To Create a New Route.

Running the route

To run the route:

  1. Open the CBRroute project you created in the section called “Creating the Fuse Integration project”.
  2. In Project Explorer, select CBRroute/Camel Contexts/src/main/resources/OSGi-INF/blueprint/blueprint.xml :

    tutRunCBRrouteCamContext
  3. Right-click it to open the context menu, then select menu:Run As[ > > Local Camel Context (without tests) > ].

    Note

    If you select Local Camel Context instead, the tooling automatically tries to run the routing context against a supplied JUnit test. Because one does not exist, the tooling reverts to running the routing context without tests. In the Chapter 8, To Test a Route with JUnit tutorial, you will create a JUnit test case and modify it specifically for testing the CBRroute 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 at the end of the output indicate that the route executed successfully:

    ...
    [Blueprint Extender: 3] BlueprintCamelContext INFO  Route: _route1 started and consuming from:Endpoint[file://src/data?noop=true]
    [Blueprint Extender: 3] BlueprintCamelContext INFO  Total 1 routes, of which 1 are started.
    [Blueprint Extender: 1] BlueprintCamelContext INFO  Apache Camel 2.18.0.redhat-000015 (CamelContext: ...) started in 0.163 seconds
    [Blueprint Extender: 3] BlueprintCamelContext INFO  Apache Camel 2.18.0.redhat-000015 (CamelContext: ...) started in 0.918 seconds
  4. To shutdown the route, click console’s shutdown button located at the top, right of the Console panel.

Verifying the route

To verify that the route executed properly:

  1. In Project Explorer, select CBRroute.
  2. Right-click it to open the context menu, then select Refresh.
  3. In Project Explorer, locate the folder target/messages/ and expand it:

    message destination
  4. Verify that the target/messages/others folder contains the six message files, message1.xml through message6.xml.
  5. Double-click message1.xml to open it in the route editor’s Design tab, then select the Source tab at the bottom, left of the canvas to see the XML code.

    Its contents should match that shown in Example 3.1, “Contents of message1.xml”.

    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

To learn more about:

Chapter 4. To Add a Content-Based Router

This tutorial shows how to add a content-based router with logging to a route.

Goals

In this tutorial you will:

  • 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 Set Header EIP after each log endpoint
    • Add an Otherwise branch to the content-based router

Prerequisites

To complete this tutorial you will need the CBRroute project you created in Chapter 2, To Create a New Route.

Adding and configuring a content-based router

To add and configure a content-based router for your route:

  1. In Project Explorer, double-click CBRroute/src/main/resources/OSGI-INF/blueprint/blueprint.xml to open your CBRroute project.
  2. On the canvas, select the To_Others node and then select the trash can above and to the right to delete it.
  3. In the Palette, open the Routing drawer and drag a Choice ( Choice icon ) pattern to the canvas and drop it in the Route_route1 container.

    The Route_route1 container expands to accommodate the Choice_choice1 node.

  4. In the Route_route1 container, select the From_from1 node and drag its connector arrow over the Choice_choice1 node, then release it:

    tutCBRaddChoice1
  5. In the Properties view, _choice1 appears in the Id field:

    tutRte1ChoicePropEdNew

    Leave the Id field as is.

  6. From the Routing drawer, drag a When ( When icon ) pattern to the canvas and drop it on the Choice_choice1 node:

    tutCBRaddWhen1

    The Choice_choice1 container expands to accommodate the When_when1 node. The warning icon decorating the When_when1 node indicates that one or more required property values must be set.

    Note

    The tooling prevents you from dropping a pattern at an invalid drop point in a Route container.

  7. On the canvas, select the When_when1 node, to open its properties in the Properties view:

    tutCBRWhen1OpenProps
  8. Click the drop-down menu icon button in the Language field to open the list of available languages, and select xpath:

    tutCBRWhen1Props
    Note

    Once you select the expression Language, the Properties view displays its properties in an indented list directly below the Language field. The Id property in this list sets the ID of the expression. The Id property following the Description field sets the ID of the When node.

  9. 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.

  10. Leave each of the remaining properties as is.

    Enabling Trim removes any leading or trailing white spaces and line breaks from the message.

  11. On the menu bar, click FileSave to save the routing context file.
  12. Click the Source tab to view the XML for the route:

    tutCBRaddedSourceV

Adding and configuring logging

To add logging to your route:

  1. In the Palette, open the Components drawer and select a Log ( Log icon ) component.
  2. Drag the Log component to the canvas and drop it on the When_when1 node:

    tutCBRlog1Added

    The When_when1 container expands to accommodate the Log_log1 node.

  3. On the canvas, select the Log_log1 node to open its properties in the Properties view.
  4. In the Message field, enter quantity requested exceeds the maximum allowed - contact customer:

    tutCBRlog1Properties
  5. Leave each of the remaining properties as is.

    Note

    In the Fuse Integration perspective’s Messages view, the tooling inserts the contents of the log node’s Id field in the Trace Node Id column for message instances, when tracing is enabled on the route (see Chapter 7, To Trace a Message Through a Route). In the Console, it adds the contents of the log node’s Message field to the log data whenever the route runs.

  6. On the menu bar, click FileSave to save the routing context file.

Adding and configuring message headers

To add and configure message headers:

  1. In the Palette, open the Transformation drawer and select a Set Header ( Set Header icon ) pattern.
  2. Drag the Set Header pattern to the canvas and drop it in the When_when1 container.

    The When_when1 container expands to accommodate the SetHeader_setHeader1 node.

  3. On the canvas, select the Log_log1 node and drag its connector arrow over the SetHeader_setHeader1 node, and then release it:

    tutSetHead1Added
  4. On the canvas, select the SetHeader_setHeader1 node to open its properties in the Properties view:

    tutSetHeadPropEdNew
  5. Click the drop-down menu icon button in the Language field to open the list of available languages, and select constant:

    tutSetHead1Properties2
  6. In the Expression field, enter InvalidOrders.
  7. In the Header Name field, enter Destination.
  8. Leave each of the remaining properties as is.
  9. In the Palette, open the Components drawer and select the File ( File icon ) component.
  10. Drag the File component to the canvas and drop it in the When_when1 container.

    The When_when1 container expands to accommodate the To_to1 node.

  11. On the canvas, select the SetHeader_setHeader1 node and drag its connector arrow over the To_to1 node, and then release it:

    tutCBRWhen1TargetFile
  12. On the canvas, select the To_to1 node to open its properties in the Properties view:

    tutCBRNewTargetFileProps1
  13. On the Details tab, replace directoryName with target/messages/invalidOrders in the Uri field, and enter _Invalid in the Id field:

    tutCBRNewTargetFileProps2
  14. On the menu bar, click FileSave to save the routing context file.
  15. Click the Source tab to view the XML for the route:

    tutCBRLogHeaderSourceV

Adding and configuring an otherwise branch

To add and configure the otherwise branch of your route:

  1. In the Palette, open the Routing drawer and select the Otherwise ( Otherwise icon ) pattern.
  2. Drag the Otherwise pattern to the canvas and drop it into the Choice_choice1 container:

    tutCBRaddOtherwise

    The Choice_choice1 container expands to accommodate the Otherwise_otherwise1 node.

  3. On the canvas, select the Otherwise_otherwise1 node to open its properties in the Properties.
  4. In the Id field, enter _else2:

    tutCBROtherwiseProps
    Note

    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 When_when1 node.

  5. In the Palette, open the Components drawer and select the Log ( Log icon ) component.
  6. Drag the Log component to the canvas and drop it on the Otherwise_else2 node:

    tutCBROtherwiseLogAdd

    The Otherwise-else2 container expands to accommodate the Log_log2 node.

  7. On the canvas, select the Log_log2 node to open its properties in the Properties view.
  8. In the Message field, enter valid order - process:

    tutCBROtherwiseLog2

    Leave each of the remaining properties as is.

  9. In the Palette, open the Transformation drawer and select the Set Header pattern.
  10. Drag the Set Header pattern to the canvas and drop it into the Otherwise_else2 container.

    The Otherwise_else2 container expands to accommodate the SetHeader_setHeader2 node.

  11. On the canvas, select the Log_log2 node and drag its connector arrow over the SetHeader_setHeader2 node, and then release it:

    tutCBRSetHead2Add
    Note

    You can collapse containers to free up space when the diagram becomes congested. To do so, select the container you want to collapse, and then click its collapse icon button:

    tutCBRcollapseWhen1Container

    To reopen the container, select it and then click its expand icon button:

    tutCBRexpandWhen1Container

    Collapsing and expanding containers in the Design tab does not affect the routing context file. It remains unchanged.

  12. On the canvas, select the SetHeader_setHeader2 node to open its properties in the Properties view.
  13. Click the drop-down menu icon button in the Language field to open the list of available languages, and select constant:

    tutCBROtherwiseSetHeadProps2
  14. In the Expression field, enter Dispatcher.
  15. In the Header Name field, enter Destination.
  16. Leave each of the remaining properties as is.
  17. In the Palette, open the Components drawer and select the File ( File icon ) component.
  18. Drag the File component to the canvas and drop it into the Otherwise_else2 container.

    The Otherwise_else2 container expands to accommodate the To_to1 node.

  19. On the canvas, select the SetHeader_setHeader2 node, and drag its connector arrow over the To_to1 node and then release it:

    tutCBROtherwiseFileAdd
  20. On the canvas, select the To_to1 node to open its properties in the Properties view.
  21. In the URI field, replace directoryName with target/messages/validOrders, and in the Id field, enter _Valid:

    tutCBROtherwiseTargFile2
  22. On the menu bar, click FileSave to save the routing context file.

    This is the completed content-based router with logs and message headers:

    tutCBRfinalDesignV
  23. 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, “XML for content-based router”.

    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:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
        https://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 id="_context1" xmlns="http://camel.apache.org/schema/blueprint">
        <route id="_route1">
            <from id="_from1" uri="file:src/data?noop=true"/>
            <choice id="_choice1">
               <when id="_when1">
                  <xpath>order/orderline/quantity/text() > /order/orderline/maxAllowed/text()</xpath>
                  <log id="_log1" message="quantity requested exceeds the maximum allowed - contact customer"/>
                  <setHeader headerName="Destination" id="_setHeader1">
                      <constant>InvalidOrders</constant>
                  </setHeader>
                  <to id="_Invalid" uri="file:target/messages/invalidOrders"/>
               </when>
               <otherwise id="_else2">
                  <log id="_log2" message="valid order - process"/>
                  <setHeader headerName="Destination" id="_setHeader2">
                      <constant>Dispatcher</constant>
                  </setHeader>
                  <to id="_Valid" uri="file:target/messages/validOrders"/>
               </otherwise>
            </choice>
        </route>
      </camelContext>
    </blueprint>

Next steps

You can run the new route as described in the section called “Running the route”.

After you run it, you can easily verify whether the route executed properly by checking the target destinations in Project Explorer:

  1. Select CBRroute.
  2. Right-click it to open the context menu, then select Refresh.
  3. Under the project root node (CBRroute), locate the folder target/messages/ and expand it.

    message destinations
  4. Check that the target/messages/invalidOrders folder contains message2.xml and message4.xml.

    In these messages, the value of the quantity element should exceed the value of the maxAllowed element.

  5. Check that the target/messages/validOrders folder contains the four message files that contain valid orders: message1.xml, message3.xml , message5.xml and message6.xml.

    In these messages, the value of the quantity element should be less than or equal to the value of the maxAllowed element.

    Note

    To view message content, double-click each message to open it in the route editor’s XML editor.

Further reading

To learn more about message enrichment see:

Chapter 5. To Add Another Route to the CBR Routing Context

This tutorial shows you how to add a second route to the blueprint.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 country folder in the CBRroute/target/messages folder.

Goals

In this tutorial you will:

  • 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

To complete this tutorial you will need the CBRroute project you modified in Chapter 4, To Add a Content-Based Router.

Note

If you skipped any tutorial after Chapter 2, To Create a New Route, you can use the prefabricated blueprint5.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

To configure the existing route for direct connection with the new route:

  1. Open your CBRroute/src/main/resources/OSGI-INF/blueprint/blueprint.xml in the route editor.
  2. On the canvas, select the Route_route1 container to open its properties in the Properties view.
  3. Scroll down to the Shutdown Route property and enter Default.
  4. On the canvas, select the terminal file node To_Valid to display its properties in the Properties view.
  5. In the Uri field, delete the existing text, and then enter direct:OrderFulfillment.
  6. In the Id field, enter _Fulfill.
Note

Instead of repurposing the existing To_Valid terminal file node, you could have replaced it with a ComponentsDirect component, configuring it with the same property values as the repurposed To_Valid node.

Adding the second route

To add a route to the routing context:

  1. In the Palette, open the Routing drawer and select the Route ( Route icon ) pattern.
  2. Drag the Route pattern to the canvas and drop it next to the Route_route1 container:

    tutRte2DropOnCanvas

    The Route pattern becomes the Route_route2 container node on the canvas.

  3. Click the Route_route2 container node to display its properties in the Properties view.
  4. Leave each of the properties as is.
Note

As your multiroute routing context grows in complexity, you may want to focus the route editor on an individual route while you work on it. To do so, in Project Explorer, double-click the route you want the route editor to display on the canvas; for example Route_route2:

tutProjExSwitchRtesOnCanvas

To display all routes in the routing context on the canvas, double-click the project’s .xml context file entry (src/main/resources/OSGI-INF/…​) at the top of the Camel Contexts folder.

Building and configuring the USA branch of the second route

  1. In the Palette, open the Components drawer and drag a Direct component ( Direct icon ) to the canvas and drop it in the Route_route2 container:

    tutCBRrte2From2Add

    The Route_route2 container expands to accommodate the From_from2 node.

  2. On the canvas, select the From_from2 node to open its properties in the Properties view:

    tutCBRrte2From2Props
  3. In the Uri field, replace name (following direct:) with OrderFulfillment, and in the Id field, enter _direct:OrderFulfillment.
  4. In the Palette, open the Routing drawer and drag a Choice ( Choice icon ) pattern to the canvas and drop it in the Route_route2 container.

    The Route_route2 container expands to accommodate the Choice_choice2 node.

  5. In the Route_route2 container, select the direct:OrderFulfillment node and drag its connector arrow over the Choice_choice2 node, then release it:

    tutCBRrte2Choice2Added
  6. In the Properties view, leave each of the Choice_choice2 node’s properties as is.
  7. In the Palette, open the Routing drawer and drag a When ( When icon ) pattern to the canvas and drop it in the Choice_choice2 container:

    tutCBRrte2When2Added

    The Choice_choice2 container expands to accommodate the When_when2 node.

  8. On the canvas, select the When_when2 node to open its properties in the Properties view:

    tutCBRrte2When2usaProps
  9. Set the node’s properties this way:

    tutCBRrte2WhenUSAprops
    • Select xpath from the Language drop-down menu.
    • Enter /order/customer/country = 'USA' in the Expression field.
    • Leave Trim enabled.
    • Enter _when/usa in the Id field.

      Note

      Once you select the expression Language, the Properties view displays its properties in an indented list directly below the Language field. The Id property in this list sets the ID of the expression. The Id property following the Description field sets the ID of the When node.

  10. In the Palette, open the Transformation drawer and drag the Set Header pattern to the canvas and drop on the When_when/usa node:

    tutCBRrte2SetHeadUSAadd

    The When_when/usa container expands to accommodate the SetHeader_setHeader3 node.

  11. On the canvas, select the SetHeader_setHeader3 node to open its properties in the Properties view:

    tutCRErte2SetHead3Props
  12. Set the node’s properties this way:

    tutCRErte2SetHeadusaProps
    • Select constant from the Language drop-down menu.
    • Enter USA in the Expression field.
    • Leave Trim enabled.
    • Enter Destination in the Header Name field.
    • Enter _setHead_usa in the Id field.
  13. In the Palette, open the Components drawer and drag a Log component ( Log icon ) to the canvas and drop it in the When_when/usa container.

    The When_when/usa container expands to accommodate the Log_log3 node.

  14. On the canvas, select the SetHeader_setHead_usa node and drag its connector arrow over the Log_log3 node, then release it:

    tutCBRrte2Log3Added
  15. On the canvas, select the Log_log3 node to open its properties in the Properties view:

    tutCBRrteLog3Props
  16. In the Properties view:

    tutCBRrte2Log3usaAdded
    • Enter Valid order - ship animals to USA customer in the Message field.
    • Enter _usa in the Id field.
    • Leave Logging Level as is.
  17. In the Palette, open the Components drawer and drag a File component ( File icon ) to the canvas and drop it in the When_when/usa container.

    The When_when/usa container expands to accommodate the To_to1 node.

  18. On the canvas, select the Log_usa node and drag its connector arrow over the To_to1 node, then release it:

    tutCBRrte2USAtermFile
  19. In the Properties view:

    tutRte2EndptUSA
    • Replace directoryName with target/messages/USA in the Uri field.
    • Enter _US in the Id field.
  20. On the menu bar, click FileSave to save the routing context file.

    The USA branch of Route_route2 should look like this:

    tutUSAbranchRte2

Building and configuring the Great Britain branch of the second route

With Route_route2 displayed on the canvas:

  1. In the Palette, open the Routing drawer and drag a When pattern ( When icon ) to the canvas and drop it in the Choice_choice2 container:

    tutCBRrte2WhenGBAdd

    The Choice_choice2 container expands to accommodate the When_when2 node.

  2. On the canvas, select the When_when2 node to open its properties in the Properties view.
  3. In the Properties view:

    • Select xpath from the Language drop-down menu.
    • Enter /order/customer/country = 'Great Britain' in the Expression field.
    • Leave Trim enabled.
    • Enter _when/gb in the Id field.
  4. In the Palette, open the Transformation drawer and drag a Set Header pattern ( Set Header icon ) to the canvas and drop it on the When_when/gb node:

    tutCBRrte2SetHeadUKAdd

    The When_when/gb container expands to accommodate the SetHeader_setHeader3 node.

  5. On the canvas, select the SetHeader_setHeader3 node to open its properties in the Properties view.
  6. In the Properties view:

    • Select constant from the Language drop-down menu.
    • Enter UK in the Expression field.
    • Leave Trim as is.
    • Enter Destination in the Header Name field.
    • Enter_setHead_uk in the Id field.
  7. In the Palette, open the Components drawer and drag a Log pattern ( Log icon ) to the canvas and drop it in the When_when/gb container.

    The When_when/gb container expands to accommodate the Log_log3 node.

  8. On the canvas, select the SetHeader_setHead_uk node and drag its connector arrow over the Log_log3 node, and then release it:

    tutCBRrte2LogUKAdd
  9. On the canvas, select the Log_log3 node to open its properties in the Properties view.
  10. In the Properties view:

    • Enter Valid order - ship animals to UK customer in the Message field.
    • Enter _uk in the Id field.
    • Leave the Logging Level as is.
  11. From the Components drawer, drag a File pattern ( File icon ) to the canvas and drop it in the When_when/gb container.

    The When_when/gb container expands to accommodate the To_to1 node.

  12. On the canvas, select the Log_uk node and drag its connector arrow over the To_to1 node, and then release it:

    tutCBRrte2UKtermFile
  13. On the canvas, select the To_to1 node to open its properties in the Properties view.
  14. In the Properties view:

    • Replace directoryName with target/messages/GreatBritain in the Uri field.
    • Enter _UK in the Id field.
  15. On the menu bar, click FileSave to save the routing context file.

    The Great Britain branch of Route_route2 should look like this:

    tutUKbranchRte2

Building and configuring the Germany branch of the second route

With Route_route2 displayed on the canvas:

  1. In the Palette, open the Routing drawer and drag a When pattern ( When icon ) to the canvas and drop it in the Choice_choice2 container:

    tutCBRrte2WhenGERAdd

    The Choice_choice2 container expands to accommodate the When_when2 node.

  2. On the canvas, select the When_when2 node to open its properties in the Properties view.
  3. In the Properties view:

    • Select xpath from the Language drop-down menu.
    • Enter /order/customer/country = 'Germany' in the Expression field.
    • Leave Trim enabled.
    • Enter _when/ger in the Id field.
  4. In the Palette, open the Transformation drawer and drag a Set Header pattern ( Set Header icon ) to the canvas and drop it on the When_when/ger node:

    tutCBRrte2SetHeadGERAdd

    The When_when/ger container expands to accommodate the SetHeader_setHeader3 node.

  5. On the canvas, select the SetHeader_setHeader3 node to open its properties in the Properties view.
  6. In the Properties view:

    • Select constant from the Language drop-down menu.
    • Enter Germany in the Expression field.
    • Leave Trim as is.
    • Enter Destination in the Header Name field.
    • Enter_setHead_ger in the Id field.
  7. In the Palette, open the Components drawer and drag a Log pattern ( Log icon ) to the canvas and drop it in the When_when/ger container.

    The When_when/ger container expands to accommodate the Log_log3 node.

  8. On the canvas, select the SetHeader_setHead_ger node and drag its connector arrow over the Log_log3 node, and then release it:

    tutCBRrte2LogGERAdd
  9. On the canvas, select the Log_log3 node to open its properties in the Properties view.
  10. In the Properties view:

    • Enter Valid order - ship animals to Germany customer in the Message field.
    • Enter _ger in the Id field.
    • Leave the Logging Level as is.
  11. From the Components drawer, drag a File pattern ( File icon ) to the canvas and drop it in the When_when/ger container.

    The When_when/ger container expands to accommodate the To_to1 node.

  12. On the canvas, select the Log_ger node and drag its connector arrow over the To_to1 node, and then release it:

    tutCBRrte2GERtermFile
  13. On the canvas, select the To_to1 node to open its properties in the Properties view.
  14. In the Properties view:

    • Replace directoryName with target/messages/Germany in the Uri field.
    • Enter _GER in the Id field.
  15. On the menu bar, click FileSave to save the routing context file.

    The Germany branch of Route_route2 should look like this:

    tutGERbranchRte2

Building and configuring the France branch of the second route

With Route_route2 displayed on the canvas:

  1. In the Palette, open the *Routing drawer and drag an Otherwise pattern ( Otherwise icon ) to the canvas and drop it in the Choice_choice2 container:

    tutCBRrte2OtherFRAdd

    The Choice_choice2 container expands to accommodate the Otherwise_otherwise1 node.

  2. On the canvas, select the Otherwise_otherwise1 node to open its properties in the Properties view.
  3. In the Properties view, enter _else/fr in the Id field.
  4. In the Palette, open the Transformation drawer and drag a Set Header pattern ( Set Header icon ) to the canvas and drop it on the Otherwise_else/fr node:

    tutCBRrte2SetHeadFRAdd

    The Otherwise_else/fr container expands to accommodate the SetHeader_setHeader3 node.

  5. On the canvas, select the SetHeader_setHeader3 node to open its properties in the Properties view.
  6. In the Properties view:

    • Select constant from the Language drop-down menu.
    • Enter France in the Expression field.
    • Leave Trim as is.
    • Enter Destination in the Header Name field.
    • Enter_setHead_fr in the Id field.
  7. In the Palette, open the Components drawer and drag a Log pattern ( Log icon ) to the canvas and drop it in the Otherwise_else/fr container.

    The Otherwise_else/fr container expands to accommodate the Log_log3 node.

  8. On the canvas, select the SetHeader_setHead_fr node and drag its connector arrow over the Log_log3 node, and then release it:

    tutCBRrte2LogFRAdd
  9. On the canvas, select the Log_log3 node to open its properties in the Properties view.
  10. In the Properties view:

    • Enter Valid order - ship animals to France customer in the Message field.
    • Enter _fr in the Id field.
    • Leave the Logging Level as is.
  11. From the Components drawer, drag a File pattern ( File icon ) to the canvas and drop it in the Otherwise_else/fr container.

    The Otherwise_else/fr container expands to accommodate the To_to1 node.

  12. On the canvas, select the Log_fr node and drag its connector arrow over the To_to1 node, and then release it:

    tutCBRrte2FRtermFile
  13. On the canvas, select the To_to1 node to open its properties in the Properties view.
  14. In the Properties view:

    • Replace directoryName with target/messages/France in the Uri field.
    • Enter _FR in the Id field.
  15. On the menu bar, click FileSave to save the routing context file.

    The France branch of Route_route2 should look like this:

    tutFRbranchRte2

Finishing up

  1. If needed, on the menu bar, select FileSave to save the routing context.

    The routes on the canvas should look like this:

    image::./images/tutCBRRte1Completed.png[Completed first route in the CBRroute routing context]

    image::./images/tutCBRRte2Completed.png[Completed second route in the CBRroute routing context]

  2. 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, “XML for dual-route content-based router”:

    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:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
        https://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 id="_context1" xmlns="http://camel.apache.org/schema/blueprint">
          <route id="_route1" shutdownRoute="Default">
              <from id="_from1" uri="file:src/data?noop=true"/>
              <choice id="_choice1">
                  <when id="_when1">
                      <xpath>/order/orderline/quantity/text() > /order/orderline/maxAllowed/text()</xpath>
                      <log id="_log1" message="quantity exceeds the maximum allowed - contact customer"/>
                      <setHeader headerName="Destination" id="_setHeader1">
                          <constant>InvalidOrders</constant>
                      </setHeader>
                      <to id="_Invalid" uri="file:target/messages/invalidOrders"/>
                  </when>
                  <otherwise id="_else2">
                      <log id="_log2" message="valid order - process"/>
                      <setHeader headerName="Destination" id="_setHeader2">
                          <constant>Dispatcher</constant>
                      </setHeader>
                      <to id="_Fulfill" uri="direct:OrderFulfillment"/>
                  </otherwise>
              </choice>
          </route>
          <route id="_route2">
              <from id="_direct:OrderFulfillment" 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 id="_usa" message="Valid order - ship to USA customer"/>
                      <to id="_US" uri="file:target/messages/USA"/>
                  </when>
                  <when id="_when/gb">
                      <xpath>/order/customer/country = 'Great Britain'</xpath>
                      <setHeader headerName="Destination" id="_setHead_uk">
                          <constant>UK</constant>
                      </setHeader>
                      <log id="_uk" message="Valid order - ship animals to UK customer"/>
                      <to id="_UK" uri="file:target/messages/GreatBritain"/>
                  </when>
                  <when id="_when/ger">
                      <xpath>/order/customer/country = 'Germany'</xpath>
                      <setHeader headerName="Destination" id="_setHead_ger">
                          <constant>Germany</constant>
                      </setHeader>
                      <log id="_ger" message="Valid order - ship to Germany customer"/>
                      <to id="_GER" uri="file:target/messages/Germany"/>
                  </when>
                  <otherwise id="_else/fr">
                      <setHeader headerName="Destination" id="_setHead_fr">
                          <constant>France</constant>
                      </setHeader>
                      <log id="_fr" message="Valid order - ship animals to France customer"/>
                      <to id="_FR" uri="file:target/messages/France"/>
                  </otherwise>
              </choice>
          </route>
      </camelContext>
    </blueprint>
Important

If the tooling added the attribute shutdownRoute=" " to the second route element (<route id="route2">), delete that attribute. Otherwise, the CBRroute project might fail to run.

Next steps

You can run the new route as described in the section called “Running the route”.

Check the end of the Console’s output. You should see these lines:

tutCBRrte2Console

Check the target destinations in Project Explorer to verify that the routes executed properly:

  1. Select CBRroute.
  2. Right-click it to open the context menu, then select Refresh.
  3. Expand the folder target/messages/ as shown in Figure 5.1, “Target message destinations in Project Explorer”. The message*.xml files should be dispersed in your target destinations like this:

    Figure 5.1. Target message destinations in Project Explorer

    message destinations
    Note

    To view message content, double-click a message to open it in the route view’s XML editor.

Further reading

To learn more about the Direct component see the Red Hat JBoss Fuse: Apache Camel Component Reference at Red Hat JBoss Fuse 6.3 documentation

Chapter 6. To Debug a Routing Context

This tutorial shows how to use the Camel debugger for only a locally running routing context. The routing context and each node with a breakpoint set must have a unique ID. The tooling automatically assigns a unique ID to the camelContext element and to components and patterns dropped on the canvas, but you can change these IDs to customize your project.

Goals

In this tutorial you will:

  • In the Design tab, 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

To complete this tutorial you will need the CBRroute project you updated in Chapter 5, To Add Another Route to the CBR Routing Context.

Note

If you skipped any tutorial after Chapter 2, To Create a New Route you can use the prefabricated blueprintContext6.xml file to work through this tutorial (for details, see Chapter 1, Using the Fuse Tooling Resource Files).

Setting breakpoints

You can set both conditional and unconditional breakpoints, but in this tutorial, you will set unconditional breakpoints only.

  1. If necessary, open your CBRroute/src/main/resources/OSGI-INF/blueprint/blueprint.xml in the route editor.
  2. In Project Explorer, expand Camel Contexts/src/main/resources/OSGI-INF/blueprint to expose both route entries.
  3. Double-click the Route_route1 entry to switch focus to Route_route1 in the Design tab.
  4. On the canvas, select the Choice_choice1 node, and then click its red icon icon to set an unconditional breakpoint:

    BPnodeIcons
    forward nav
    BPnodeIcons2
    Note

    In the route editor, you can disable or delete a specific breakpoint by clicking the node’s gray icon icon or its delete icon icon, respectively. You can delete all set breakpoints by right-clicking the canvas and selecting Delete all breakpoints.

  5. Repeat [setBPstep] to set an unconditional breakpoint on the following Route_Route1 nodes:

    • Log_log1
    • SetHeader_setHeader1
    • To_Invalid
    • Log_log2
    • SetHeader_setHeader2
    • To_Fulfill
  6. In Project Explorer, double-click Route_route2 under src/main/resources/OSGI-INF/blueprint to open Route_route2 on the canvas.
  7. Repeat [setBPstep] to set an unconditional breakpoint on the following Route_Route2 nodes:

    • Choice_choice2
    • SetHeader_setHead_usa
    • Log_usa
    • To_US
    • SetHeader_setHead_uk
    • Log_uk
    • To_UK
    • SetHeader_setHead_ger
    • Log_ger
    • To_GER
    • SetHeader_setHead_fr
    • Log_fr
    • To_FR

Stepping through the CBRroute routing context

You can step through the routing context in two ways:

  • Step over ( Step Over icon ) - Jumps to the next node of execution in the routing context, regardless of breakpoints.
  • Resume ( Resume icon ) - Jumps to the next active breakpoint in the routing context.
Note

You can temporarily narrow then later re-expand the debugger’s focus by disabling and re-enabling the breakpoints you set in the routing context. This enables you, for example, to focus on problematic nodes in your routing context. To do so, open the Breakpoints tab and clear the check box of each breakpoint you want to temporarily disable. Then use Resume icon to step through the route. The debugger will skip over the disabled breakpoints.

  1. In Project Explorer, expand the root node CBRroute to expose the blueprint.xml file in the Camel Contexts folder.
  2. Right-click the blueprint.xml file to open its context menu, and then click menu:Debug As…​[ > > Local Camel Context > ].

    The Camel debugger suspends execution at the first breakpoint it encounters and asks whether you want to open Debug perspective now:

    tutCnfrmPerspSwitch
  3. Click Yes.

    Note

    If 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 menu:Window[ > > Open Perspective > > Debug > ].

    Debug perspective opens with the routing context suspended at _choice1 in Route1 [blueprint.xml] as shown in the Debug view:

    tutDebugPerspOpen1
    Note

    Breakpoints 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.

  4. In the 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.

  5. Click Resume icon to step to the next breakpoint, _log2 in Route1 [blueprint.xml]:

    tutDBResumeLog2Rte1
  6. Expand the nodes in the Variables view to examine the variables that have changed since the last breakpoint at _choice1 in Route1 [blueprintxt.xml].
  7. Click Resume icon to step to the next breakpoint, _setHeader2 in Route1 [blueprint.xml].

    Examine the variables that changed since the breakpoint at _log2 in Route1 [blueprint.xml].

  8. In the Debug view, click _log2 in Route1 [blueprint.xml] to populate the Variables view with the variable values from the breakpoint _log2 in Route1 [blueprint.xml] for a quick comparison.

    In the Debug view, you can switch between breakpoints within the same message flow to quickly compare and monitor changing variable values in the Variables view.

    Note

    Message flows can vary in length. For messages that transit the InvalidOrders branch of Route_route1, the message flow is short. For messages that transit the ValidOrders branch of Route_route1, which continues on to Route_route2, the message flow is longer.

  9. 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 the Debug view, tagged with a new breadcrumb ID:

    tutDBviewNextMsg

    In this case, ID-janemurpheysmbp-home-55846-1471374645179-0-3 identifies the second message flow, corresponding to message2.xml having entered the routing context. Breadcrumb IDs are incremented by 2.

    Note

    Exchange 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 of message2.xml, its ExchangeId and MessageId are ID-janemurpheysmbp-home-55846-1471374645179-0-4.

  10. When message3.xml enters the breakpoint _choice1 in Route_route1 [blueprint.xml], examine the Processor variables. The values displayed are the metrics accumulated for message1.xml and message2.xml, which previously transited the routing context:

    tutMsg3Choice1Stats

    Timing metrics are in milliseconds.

  11. Continue stepping each message through the routing context, examining variables and console output at each processing step. When message6.xml enters the breakpoint To_GER in Route2 [blueprint.xml], the debugger begins shutting down the breadcrumb threads.
  12. In the Menu bar, click Terminate icon to terminate the Camel debugger. This will cause the Console to terminate, but you will have to manually clear the output.

    Note

    With a thread or endpoint selected under the Camel Context node in the Debug view, you need to click Terminate icon twice - first to terminate the thread or endpoint and second to terminate the Camel Context, thus the session.

  13. In the Menu bar, right-click tutDebugPersp to open the context menu, and then select Close to close Debug perspective.

    Doing so automatically returns you to perspective from which you launched the Camel debugger.

  14. In Project Explorer, open the project’s context menu, and select Refresh to refresh the display.

    Note

    If you terminated the session prematurely, before all messages transited the routing context, you might see, under the CBRroute/src/data folder, a message like this: message3.xml.camelLock. You need to remove it before you run the debugger on the project again. To do so, double-click the .camelLock message to open its context menu, and then select Delete. When asked, click OK to confirm deletion.

  15. Expand the CBRroute/target/messages/* directories to check that the messages were delivered to their expected destinations:

    tutDualCBRrteVerify
  16. Leave the routing context as is, with all previous breakpoints set and enabled.

Changing the value of a variable

In this session, you will add variables to a watch list to easily check how their values change as messages pass through the routing context. You will also change the value of a variable in the body of two messages and observe how the change affects each message’s route through the routing context.

  1. Follow [startDebugger1] through [startDebugger3] in the section called “Stepping through the CBRroute routing context” to rerun the Camel debugger on the CBRroute project.
  2. With message1 stopped at the first breakpoint, _choice1 in Route1 [blueprint.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:

    1. In the Variables view, expand the appropriate category to expose the target variable:
    2. Right-click the variable (in this case, NodeId in the Exchange category) to open the context menu and select Watch:

      FTVarNodeIDWatch

      The Expressions tab opens, listing the variable you selected to watch:

      FTWatchM1NodeId
    3. Repeat [selectVariable] for each of the three remaining variables.
    4. Switch back to the Variables view.
  3. Step message1 through the routing context until it reaches the fourth breakpoint, _Fulfill in Route1 [blueprint.xml].
  4. In the Variables view, expand the Message category.
  5. Repeat [selectVariable] to add the variable Destination to the watch list.

    The Expressions view should now contain these variables:

    FTWatchM1R1toFfil
    Note

    The pane below the list of variables displays the value of the selected variable.

    Note

    The Expressions view retains all variables you add to the list until you explicitly remove them.

  6. Step message1 through the rest of the routing context.
  7. Stop message2 at _choice1 in Route1 [blueprint.xml].
  8. In the Variables view, expand the Message category to expose the MessageBody variable.
  9. Right-click MessageBody to open its context menu, and select Change Value…​:

    tutVarChngMenuMsg2
  10. Change the value of quantity from 3 to 2:

    tutChgVarsMsg2

    This changes the in-memory value only.

  11. Click OK.
  12. Switch to the 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:

    FTWatchM2R1toFfilVarChng
    Note

    Creating a watch list makes it easy for you to quickly check the current value of multiple variables of interest.

  13. Click Resume icon to step to the next breakpoint.

    Instead of following the branch leading to To_Invalid, message2 now follows the branch leading toTo_Fulfill and Route_route2:

    tutCamCntxtMsg2toFulfill
  14. Step message2 through the routing context, checking the Debug view, the Variables view, and the Console output at each step.
  15. Stop message3 at _choice1 in Route1 [blueprint.xml].
  16. Switch to the Breakpoints view, and disable all breakpoints (13) listed below _choice1:

    tutBreakptsDisabled
  17. Click Resume icon to step to the next breakpoint:

    tutMsg3toFulfillRte1

    The debugger jumps to _FulFill in Route1 [blueprint.xml].

  18. Click Resume icon again to step to the next breakpoint:

    tutMsg3toUKRte2

    The debugger jumps to _UK in Route2 [blueprint.xml].

  19. In the Breakpoints view, re-enable all disabled breakpoints.
  20. Switch back to the Variables view.
  21. Click Resume icon to step to the next breakpoint, and stop message4 at _choice1 in Route1 [blueprint.xml].
  22. Right-click MessageBody to open its context menu, and select Change Value…​.
  23. Change the value of quantity from 5 to 4:

    tutChnVarMsg4
  24. Click OK.
  25. Switch to the Expressions view, and select the MessageBody variable to check the value of quantity in the body of message4.
  26. Repeat [varChgRestart1] and [varChgRestart2] to step message4 through the routing context.
  27. Click Resume icon repeatedly to quickly step message5 and message6 through the routing context.
  28. In the tool bar, click Terminate icon to terminate the Camel debugger:

    tutDBTerminateNorm

    This will also cause the Console to terminate, but you will have to click its Clear output icon button to clear the output.

  29. In the Menu bar, right-click tutDebugPersp to open the context menu, and then select Close to close Debug perspective.

    Doing so automatically returns you to the perspective from which you launched the Camel debugger.

  30. In Project Explorer, open the project’s context menu, and select Refresh to refresh the display.
  31. Expand the CBRroute/target/messages/* directories to check whether the messages were delivered as expected:

    tutPETargetDestsChngedVars

    You should see that no messages were sent to the invalidOrders. Instead, message2.xml should appear in the USA folder, and message4.xml should appear the GreatBritain folder.

Next steps

Next you will trace messages through your routing context to see where you can optimize and fine tune your routing context’s performance, as described in Chapter 7, To Trace a Message Through a Route.

Chapter 7. To Trace a Message Through a Route

This tutorial shows you how to trace a message through a route.

Goals

In this tutorial you will:

  • 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

To complete this tutorial you will need the CBRroute project you updated in Chapter 5, To Add Another Route to the CBR Routing Context.

Note

If you skipped any tutorial after Chapter 2, To Create a New Route, you can use the prefabricated blueprint6.xml file to work through this tutorial (for details, see Chapter 1, Using the Fuse Tooling Resource Files).

Accessing Fuse Integration perspective

If you are not already working in Fuse Integration perspective:

  1. Click the Open Perspective icon button on the right side of the tool bar, and then select Fuse Integration from the list:

    tutPerspListFIPselected

    Fuse Integration perspective opens in the default layout:

    TutFIP 63
  2. Drag the JMX Navigator tab to the far right of the Terminal tab and drop it there:

    ftTutFIPrearrange

    This arrangement provides more space for Diagram View to display the routing context’s nodes graphically, which makes it easier for you to visually trace the path that messages take in traversing the routing context.

    Note

    To make it easy to access a routing context .xml file, especially when a project consists of multiple contexts, the tooling lists them under the Camel Contexts folder in Project Explorer.

    Additionally, all routes in a routing context are displayed as icons directly under their context file entry. To display a single route in the routing context on the canvas, double-click its icon in Project Explorer. To display all routes in the routing context, double-click the context file entry.

    TutCamelContextsFolderPE

Starting message tracing

To start message tracing on the CBRroute project:

  1. In Project Explorer, expand the CBRroute project to expose src/main/resources/OSGI-INF/blueprint/blueprint.xml.
  2. Right-click src/main/resources/OSGI-INF/blueprint/blueprint.xml to open the context menu.
  3. Select menu:Run As[ > > Local Camel Context (without tests) > ].

    Note

    If you select Local Camel Context, the tooling reverts to running without tests 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.

  4. In JMX Navigator, expand Local Processes.

    When you first expand Local Processes, you see the node maven[Id][Disconnected]:

    tutMsgTrJMXLocalProcessess

    When you click this node, it changes to Local Camel Context[Id][Disconnected] (retaining the same Id as its predecessor):

    tutMsgTrJMXLocalCamCntxt
  5. Double click Local Camel Context[Id][Disconnected] to connect to it, and then expand the elements of your route:

    tutMsgTrJMXLCCexpanded
  6. Right-click the _context1 node to open the context menu, and select Start Tracing:

    tutTraceStart

    The tooling displays a graphical representation of your routing context in Diagram View:

    tutDiagramNodes

Dropping messages on the running CBRroute project

To drop messages on the running CBRroute project:

  1. In Project Explorer, expand CBRroute/src/data, so you can access the message files (message1.xml through message6.xml):

    tutMsgFiles
  2. Drag message1.xml and drop it on the _context1>Endpoints>file>src/data?noop=true node in JMX Navigator:

    tutJMXLocalCntxtExpanded

    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 the _context1 node in JMX Navigator.

    Note

    The Local Camel Context[xxx] tree collapses to the _context1 node after you drop the next message on the input src/data?noop=true 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 the src/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

You need to initialize Messages View before it will display message traces. You also need to configure the columns in Messages View if you want them to persist across all message traces.

  1. Switch from Console to Messages View.
  2. Click the _context1 node in JMX Navigator to initialize Messages View with message1.xml's details.

    Note

    You 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 menu:View Menu[ > > Configure Columns…​ > ] method instead.

  3. In Messages View, click the View Menu icon icon on the panel’s menu bar, and select Configure Columns…​ to open the Configure Columns wizard:

    TutConfigColsDefaults
    Note

    Notice 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.

  4. In the Configure Columns wizard, select and order the columns this way:

    tutMsgVCnfgColsMnu

    These columns and their order will persist in Messages View until you change them again.

Arranging Diagram View

To see all message flow paths clearly, you’ll probably need to rearrange the nodes by dragging them to fit neatly in Diagram View. You may also need to adjust the size of the other views and tabs in Red Hat JBoss Developer Studio to allow Diagram View to expand.

Stepping through message traces

To step through the message traces:

  1. In Messages View, click the refresh (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 input src node in JMX Navigator, you need to refresh Messages View to populate it with the message traces.

  2. Click one of the message traces to see more details about it in Properties view:

    tutTraceDetails2

    The tooling displays the details about a message trace (including message headers when they are set) in the top half of the Properties view and the contents of the message instance in the bottom half of the Properties view. 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:

    TutMsgTraceDiagNode

Finishing up

  1. Drag message2.xml and drop it on the_context1>Endpoints>file>src/data?noop=true node in JMX Navigator.

    Hover over each node in the tree until you expose the src/data?noop=true node, then drop message2.xml on it.

  2. Switch from Console to Messages View.
  3. In Messages View, click the refresh (Refresh button) on top, right of the panel’s menu bar to populate the view with message2.xml's message traces.

    Note

    You can repeat [msg1drag] through [msgView] for the remaining messages in CBRroute/src/data/ at any time, as long as tracing remains enabled.

    On each subsequent drop, remember to click the refresh (Refresh button) on the panel’s menu bar to populate Messages View with the new message traces.

    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:

    tutTraceFIP 63

    Hovering over the displayed metrics reveals additional metrics about message flow:

    tutDVnodeMetrics
    • 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
  4. When done:

    • In JMX Navigator, right-click _context1 and select Stop Tracing Context from the context menu.
    • Open the Console and click the Stop icon button in the upper right of the panel to stop the Console. Then click the Clear icon button to clear console output.

Next steps

After you create a JUnit test case for your project, you can run your project as a Local Camel Context, instead of Local Camel Context (without tests). See Chapter 8, To Test a Route with JUnit for details.

Chapter 8. To Test a Route with JUnit

This tutorial shows you how to use the New Camel Test Case wizard to create a test case for your route and then test the route.

Overview

The New Camel Test Case wizard generates a boilerplate JUnit test case. When you create or modify a route (for example, adding more processors to it), you create or modify the generated test case to add expectations and assertions specific to the route you created or updated.This ensures that the test is valid for the route.

Goals

In this tutorial you will:

  • Create the /src/test/ folder to store the JUnit test case
  • Generate the 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

To complete this tutorial you need the CBRroute project you used in Chapter 7, To Trace a Message Through a Route

Note

If you skipped any tutorial after Chapter 2, To Create a New Route, you can use the prefabricated blueprintContext6.xml file to work through this tutorial (for details, see Chapter 1, Using the Fuse Tooling Resource Files).

Delete any trace-generated messages from the CBRroute project’s /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

tutTraceGenMsgs

Select all trace-generated messages in batch, right-click to open the context menu, and select Delete.

Creating the src/test folder

Before you create a JUnit test case for the CBRroute project, you must create a folder for it that is included in the build path:

  1. In Project Explorer, right-click the CBRroute project’s root to open the context menu, and then select menu:New[ > > Folder > ].
  2. In the New Folder dialog, in the project tree pane, expand the CBRroute node and select the src folder.

    Make sure CBRroute/src appears in the Enter or select the parent folder field.

  3. In Folder name, enter /test/java:

    tutCreateJUnitTestFolder
  4. Click Finish.

    In Project Explorer, the new src/test/java folder appears under the src/main/resources folder:

    tutTestFolderAdded
  5. Verify that the new /src/test/java folder is included in the build path.

    1. In Project Explorer, right-click the /src/test/java folder to open the context menu.
    2. Select Build Path to see the menu options:

      The menu option Remove from Build Path verifies that the /src/test/java folder is currently included in the build path:

      tutJavaFolderOnBldPath

Creating the JUnit test case

To create a JUnit test case for the CBRroute project:

  1. In Project Explorer, select src/test/java.
  2. Right-click it to open the context menu, and then select menu:New[ > > Camel Test Case > ]:

    NewCamTstCaseTut
  3. In the Camel JUnit Test Case wizard, make sure the Source folder field contains CBRroute/src/test/java. To find the proper folder, click browse button .
  4. In the Package field, enter tutorial.cbr.route. This is the package that will include the new test case.
  5. Next to the Camel XML file under test field, click Browse to open a file explorer configured to screen for XML files, and then select the CBRroute project’s blueprint.xml file:

    tutCamXMLUnderTst
  6. Click OK.

    tutCamJUnitTstPgComplete
    Note

    The Name field defaults to BlueprintXmlTest.

  7. Click Next to open the Test Endpoints page.
  8. By default, all endpoints are selected and will be included in the test case. Click Finish.

    Note

    If prompted, add JUnit to the build path.

The artifacts for the test are added to your project and appear in Project Explorer under 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 BlueprintXmlTest extends CamelBlueprintTestSupport {

	// TODO Create test message bodies that work for the route(s) being tested
	// Expected message bodies

	protected object[] expectBodies = {
        "<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;
	@Produce(uri = "direct:OrderFulfillment")
	protected ProducerTemplate input2Endpoint;

	// 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;
	@EndpointInject(uri = "mock:output6")
	protected MockEndpoint output6Endpoint;

	@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/invalidOrders").to(outputEndpoint);
				from("file:target/messages/GreatBritain").to(output3Endpoint);
				from("file:target/messages/Germany").to(output4Endpoint);
				from("file:target/messages/USA").to(output2Endpoint);
				from("file:target/messages/France").to(output5Endpoint);
			}
		});

		// Define some expectations

		// TODO Ensure expectations make sense for the route(s) we're testing
		outputEndpoint.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/blueprint.xml";
	}

}

This generated JUnit test case is insufficient for the CBRroute project, and it will fail to run successfully. You need to modify it and the project’s pom.xml, as described in the section called “Modifying the BlueprintXmlTest file” and the section called “Modifying the pom.xml file”.

Modifying the BlueprintXmlTest file

You must modify the BlueprintXmlTest.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

    1. In Project Explorer, expand the CBRroute project to expose the BlueprintXmlTest.java file:

      tutBlueprintXMLTestProjExp
    2. Double-click BlueprintXmlTest.java to open the file in the tooling’s Java editor.
    3. In the Java editor, click the expand button next to import org.apache.camel.EndpointInject; to expand the list.
    4. Add the two lines shown below. Adding the first line will cause an error that will be resolved when you update the pom.xml file as instructed in the next section.

      tutBPTstImportFileUtils
    5. Scroll down to the lines that follow directly after // Expected message bodies.
    6. Replace those lines — protected Object[] expectedBodies={ …​…​ expectedBody2</something>"}; —  with the protected String body#; lines shown here:

      tutCamCntxtFile2
    7. Scroll down to the line public void testCamelRoute() throws Exception {, and insert directly after it the lines body# = FileUtils.readFileToString(new File("src/data/message#.xml"), "UTF-8"); shown below. These lines will indicate an error until you update the pom.xml file as instructed in the next section.

      tutCamCntxtFile3
    8. Scroll down to the lines that follow directly after // TODO Ensure expectations make sense for the route(s) we’re testing.
    9. Replace the block of code that begins with outputEndpoint.expectedBodiesReceivedInAnyOrder(expectedBodies); and ends with …​inputEndpoint.sendBody(expectedBody); } with the lines shown here:

      tutCamCntxtFile4

      Leave the remaining code as is.

    10. Save the file.
    11. Check that your updated BlueprintXmlTest.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;
      
      public class BlueprintXmlTest 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, you must read
      	// the content of the 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 String object, but you must
      		// add a dependency to the commons-io project to the CBRroute pom.xml file
      		body1 = FileUtils.readFileToString(new File("src/data/message1.xml"), "UTF-8");
      		body3 = FileUtils.readFileToString(new File("src/data/message3.xml"), "UTF-8");
      		body5 = FileUtils.readFileToString(new File("src/data/message5.xml"), "UTF-8");
      		body6 = FileUtils.readFileToString(new File("src/data/message6.xml"), "UTF-8");
      
      		// Invalid Orders
      		body2 = FileUtils.readFileToString(new File("src/data/message2.xml"), "UTF-8");
      		body4 = FileUtils.readFileToString(new File("src/data/message4.xml"), "UTF-8");
      
      		context.addRoutes(new RouteBuilder() {
      			@Override
      			public void configure() throws Exception {
      				from("file:target/messages/invalidOrders").to(outputEndpoint);
      				from("file:target/messages/GreatBritain").to(output3Endpoint);
      				from("file:target/messages/Germany").to(output4Endpoint);
      				from("file:target/messages/USA").to(output2Endpoint);
      				from("file:target/messages/France").to(output5Endpoint);
      			}
      		});
      
      		// 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/blueprint.xml";
      	}
      
      }

Modifying the pom.xml file

You need to add a dependency on the commons-io project to the CBRroute project’s pom.xml file:

  1. In Project Explorer, double-click pom.xml, located below the target folder, to open the file in the tooling’s XML editor.
  2. Click the pom.xml tab at the bottom of the page to open the file for editing.
  3. Add these lines to the end of the <dependencies> section:

    <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.5</version>
           <scope>test</scope>
    </dependency>
  4. 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>co</groupId>
      <artifactId>camel-blueprint</artifactId>
      <version>1.0.0-SNAPSHOT</version>
      <packaging>bundle</packaging>
      <name>Camel Blueprint Quickstart</name>
      <description>Empty Camel Blueprint Example</description>
    
      <licenses>
        <license>
          <name>Apache License, Version 2.0</name>
          <url>http://www.apache.org/licenses/LICENSE-2.0.html</url>
          <distribution>repo</distribution>
        </license>
      </licenses>
    
      <properties>
        <camel.version>2.18.1.redhat-000015</camel.version>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <version.maven-bundle-plugin>2.3.7<</version.maven-bundle-plugin>
        <jboss.fuse.bom.version>6.3.0.redhat-187</jboss.fuse.bom.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      </properties>
    
      <dependencyManagement>
        <dependencies>
          <dependency>
            <groupId>org.jboss.fuse.bom</groupId>
            <artifactId>jboss-fuse-parent</artifactId>
            <version>${jboss.fuse.bom.version}</version>
            <type>pom</type>
            <scope>import</scope>
          </dependency>
        </dependencies>
      </dependencyManagement>
    
      <dependencies>
        <dependency>
          <groupId>org.apache.camel</groupId>
          <artifactId>camel-core</artifactId>
          <version>${camel.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.camel</groupId>
          <artifactId>camel-blueprint</artifactId>
          <version>${camel.version}</version>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
        </dependency>
        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
        </dependency>
        <dependency>
          <groupId>org.apache.camel</groupId>
          <artifactId>camel-test-blueprint</artifactId>
          <version>${camel.version}</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.5</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <repositories>
        <repository>
          <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <id>fuse-public-repository</id>
          <name>FuseSource Community Release Repository</name>
          <url>https://repo.fusesource.com/nexus/content/groups/public</url>
        </repository>
        <repository>
          <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <id>red-hat-ga-repository</id>
          <name>Red Hat GA Repository</name>
          <url>https://maven.repository.redhat.com/ga</url>
        </repository>
        <repository>
          <id>fuse-ea</id>
          <url>http://download.eng.brq.redhat.com/brewroot/repos/jb-fuse-6.2-build/latest/maven</url>
        </repository>
        <repository>
          <id>redhat-ea-repository</id>
          <url>https://maven.repository.redhat.com/earlyaccess/all</url>
        </repository>
      </repositories>
    
      <pluginRepositories>
        <pluginRepository>
          <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <id>fuse-public-repository</id>
          <name>FuseSource Community Release Repository</name>
          <url>https://repo.fusesource.com/nexus/content/groups/public</url>
        </pluginRepository>
        <pluginRepository>
          <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
          </releases>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <id>red-hat-ga-repository</id>
          <name>Red Hat GA Repository</name>
          <url>https://maven.repository.redhat.com/ga<url>
        </pluginRepository>
        <pluginRepository>
          <id>fuse-ea</id>
          <url>http://download.eng.brq.redhat.com/brewroot/repos/jb-fuse-6.2-build/latest/maven</url>
        </pluginRepository>
        <pluginRepository>
          <id>redhat-ea-repository</id>
          <url>https://maven.repository.redhat.com/earlyaccess/all</url>
        </pluginRepository>
        <pluginRepository>
          <id>camelStaging</id>
          <url>https://repository.jboss.org/nexus/content/repositories/fusesource_releases_external-2384</url>
        </pluginRepository>
      </pluginRepositories>
    
      <build>
        <defaultGoal>install</defaultGoal>
        <plugins>
          <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>${version.maven-bundle-plugin}</version>
            <extensions>true</extensions>
            <configuration>
              <instructions>
                <Bundle-SymbolicName>CBRroute</Bundle-SymbolicName>
                <Bundle-Name>Empty Camel Blueprint Example [CBRroute]</Bundle-Name>
              </instructions>
            </configuration>
          </plugin>
          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
              <source>1.8</source>
              <target>1.8</target>
            </configuration>
          </plugin>
          <plugin>
            <artifactId>maven-resources-plugin</artifactId>
            <version>3.0.1</version>
            <configuration>
              <encoding>UTF-8</encoding>
            </configuration>
          </plugin>
          <plugin>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-maven-plugin</artifactId>
            <version>${camel.version}</version>
            <configuration>
              <useBlueprint>true</useBlueprint>
            </configuration>
          </plugin>
        </plugins>
      </build>
    
    </project>

Running the JUnit test

To run the test:

  1. Switch to JBoss perspective to free up more workspace.
  2. Select the project root, CBRroute, in the Project Explorer.
  3. Open the context menu.
  4. Select menu:Run As[ > JUnit Test].

    Note

    By default, the 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.)

  5. If the test runs successfully, you’ll see something like this:

    JUnit success
    Note

    Sometimes the test fails the first time JUnit is run on a project. Rerunning the test ususally results in a successful outcome.

    When the test does fail, you’ll see something like this:

    JUnit failure
    Note

    JUnit will fail if your execution environment is not set to Java SE 8 or 7. 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 menu:Run As[ > > Run Configurations > > JRE > ]. Click the Environments button next to the Execution environment field to locate and select a Java SE 8 or 7 environment.

  6. Examine the output and take action to resolve any test failures.

    To see more of the errors displayed in the JUnit panel, click Maximize button on the panel’s menu bar to maximize the view.

    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

To learn more about JUnit testing see JUnit.

Chapter 9. To Publish a Fuse Project to JBoss Fuse

This tutorial walks you through the process of publishing an Apache Camel project to Red Hat JBoss Fuse. It assumes that you have an instance of Red Hat JBoss Fuse installed on the same machine on which you are running the Red Hat JBoss Fuse Tooling.

Goals

In this tutorial you will:

  • 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

To complete this tutorial you will need:

Defining a Red Hat JBoss Fuse Server

To define a server:

  1. Open Fuse Integration perspective.
  2. Click the Servers tab in the lower, right panel to open the Servers view.
  3. Click the link No servers are available. Click this link to create a new server…​ to open the Define a New Server page.

    Note

    To define a new server when one is already defined, right-click inside the Servers view to open the context menu, and then select menu:New[ > > Server > ].

  4. Expand the JBoss Fuse node to expose the available server options:

    tutDefineNewServer
  5. Click JBoss Fuse 6.3 Server.
  6. Accept the defaults for Server’s host name (localhost) and Server name (JBoss Fuse 6.3 Runtime Server), and then click Next to open the JBoss Fuse Runtime page:

    tutFuseRuntimeDef1
    Note

    If you do not have JBoss Fuse 6.3 already installed, you can download it now using the Download and install runtime…​ link.

    Note

    If you have already defined a JBoss Fuse 6.3 server, the tooling skips this page, and instead displays the configuration details page shown in [configDetails].

  7. Accept the default for Name (JBoss Fuse 6.3 Runtime).
  8. Click Browse next to the Home Directory field, to navigate to the JBoss Fuse 6.3 installation and select it.
  9. Select the runtime JRE from the drop-down menu next to Execution Environment.

    Select either JavaSE-1.8 (recommended) or JavaSE-1.7. If neither appears as an option, click the Environments…​ button and select either version from the list.

    Note

    The JBoss Fuse 6.3 server requires Java 8 (recommended) or Java 7. To select either version for the Execution Environment, you must have previously installed it.

  10. Leave the Alternate JRE option as is.

    tutFuseRuntimeDef2
  11. Click Next to save the runtime definition for JBoss Fuse 6.3 Server and open the JBoss Fuse server configuration details page:

    NewServerDetailsTut
  12. 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.

  13. 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.

    Note

    If 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 [configDetails].

    If one has not been set, you can either add one to that file using the format user=password,role (for example, joe=secret,Administrator), or you can set one using the karaf jaas command set:

    • jaas:realms — to list the realms
    • jaas:manage --index 1 — to edit the first (server) realm
    • jaas:useradd <username> <password> — to add a user and associated password
    • jaas:roleadd <username> Administrator — to specify the new user’s role
    • jaas: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 command JBossFuse:karaf@root>jaas:users.

  14. 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 karaf jaas commands.

  15. Click Finish.

    JBoss Fuse 6.3 Runtime Server [stopped, Synchronized] appears in the Servers view.

  16. In the Servers view, expand JBoss Fuse 6.3 Runtime Server [stopped, Synchronized]:

    JBFuseServersView

    JMX[Disconnected] appears as a node under JBoss Fuse 6.3 Runtime Server [stopped, Synchronized] entry.

Configuring the publishing options

Using publishing options, you can configure how and when your CBRroute project is published to a running server:

  • 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 this tutorial, you are going to configure immediate publishing upon saving changes to the CBRroute project. To do so:

  1. In the Servers view, double-click the JBoss Fuse 6.3 Runtime Server [stopped, Synchronized] entry to display its overview:

    srvEditorPubOpts
  2. On the server’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.

Note

To configure manual publishing:

  • Enable the Never publish automatically option on the server’s Overview page.
  • Disable the If server started, publish changes immediately option on the server’s Add and Remove page.

Then to manually publish changes made to selective resources configured on the running server, use the Full Publish option on the resource’s context menu in the Servers view. The Incremental Publish option is not supported and clicking it results in a full publish.

Starting the Red Hat JBoss Fuse server

This section provides instructions for starting the Fuse server and then assigning the CBRroute module to it for immediate publishing.

  1. In the Servers view, select JBoss Fuse 6.3 Runtime Server and click start server icon to start it.

    Important

    A warning that the host identification has changed may appear. Click yes to replace the key only if the JBoss Fuse 6.3 server runtime is installed on the same machine where Red Hat JBoss Fuse Tooling is running! Otherwise click no and contact your system administrator.

  2. Wait a few seconds for JBoss Fuse 6.3 Server to start up. When it does:

    • The Terminal view displays the JBoss Fuse splash screen:

      tutServerStartShellV
    • Servers view displays:

      tutServerStartServerV
    • JMX Navigator displays JBoss Fuse 6.3 Runtime Server[Disconnected]:

      tutServerStartJMXNav
  3. In the Servers view, right-click JBoss Fuse 6.3 Runtime Server [Started] to open the context menu.
  4. Select Add and Remove to open the Add and Remove page:

    tutAddRemove1

    Make sure the option If server is started, publish changes immediately is checked.

  5. Select CBRroute and click Add to assign it to the JBoss Fuse server;

    tutAddRemove2
  6. Click Finish.

    tutCBRrtePublishedSrvV
    • JBoss Fuse 6.3 Runtime Server [Started, Synchronized]

      Note

      For a server, synchronized means that all modules published on the server are identical to their local counterparts.

    • CBRroute [Started, Synchronized]

      Note

      For 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]

Connecting to the JBoss Fuse 6.3 runtime server

When you connect to the JBoss Fuse 6.3 Runtime Server, you can see the published elements of your CBRroute project and interact with them. The instructions in this section will show a display such as the following:

tutSrvJMXConnected
  1. In the Servers view, double-click JMX[Disconnected] to connect to the runtime server.
  2. Expand the Camel folder in the Servers view or JMX Navigator to expose the elements of the CBRroute.

    You can interact with the CBRroute routing context using either the 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.

    Note

    Once the _context1 node appears in JMX Navigator under Server Connections (or in the Servers view under JMX[Connected]), you can start tracing on it, as described in Chapter 7, To Trace a Message Through a Route.

  3. Click the Bundles node to populate the Properties view with the list of bundles installed on the JBoss Fuse 6.3 Runtime Server:

    tutCBRrouteBundleInstall

    Start typing CBRroute in the Properties view’s Search field to quickly determine whether your project’s CBRroute bundle is included in the list. Note that it is the last bundle in the list, identified by its Symbolic Name, CBRroute, which is the name you gave your project when you created it.

    Note

    Alternatively, you can issue the osgi:list command in the Terminal view to see a generated list of bundles installed on the JBoss Fuse server runtime. The tooling uses a different naming scheme for OSGi bundles displayed by the osgi:list command. In this case, the command returns Empty Camel Blueprint Project [CBRroute], which appears at the end of the list of installed bundles.

    In the <build> section of project’s pom.xml file, you can find the bundle’s symbolic name and its bundle name (OSGi) listed in the maven-bundle-plugin entry:

    tutBundleNamesPom

Uninstalling the CBRroute project

Note

You do not need to disconnect the JMX connection or stop the server to uninstall a published resource.

To remove the CBRroute resource from the JBoss Fuse runtime server:

  1. In the Servers view, right-click JBoss Fuse 6.3 Runtime Server to open the context menu.
  2. Select Add and Remove:

    tutUnpubCBRroute
  3. In the Configured column, select CBRroute, and then click Remove to move the CBRroute resource to the Available column.
  4. Click Finish.
  5. In the Servers view, right-click JMX[Connected] to open the context menu, and then click Refresh.

    The Camel tree under JMX[Connected] disappears.

    Note

    In JMX Navigator, the Camel tree under Server Connections > JBoss Fuse 6.3 Runtime Server[Connected] also disappears.

  6. With the Bundles page displayed, start typing CBRroute` in the Properties view’s Search field to verify that the bundle has been removed.

Legal Notice

Copyright © 2018 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.