0

I'm busy coming to grips with Camel and Karaf. I've built a project with two bundles:

  • Bundle A contains a Blueprint Camel route
  • Bundle B contains a pure Java route

I followed the instructions from Jamie Goodyear's Karaf Cookbook

Both routes are super simple and I deploy them using a feature file. They deploy perfectly and also run exactly as planned:

Bundle A moves files from /tmp/in to /tmp/out Bundle B moves files from /tmp/in2 to tmp/out2

All good.

However, if I run the Karaf command camel:route-list then only the Blueprint route is shown

Also, if I run camel:context-list then only the context defined in Bundle A is shown.

Just to reiterate, both routes work correctly, it's just the the Java ones aren't showing up in the list.

Am I missing something here?

Here's my Java Route:

public class FileRouter extends RouteBuilder {
    public void configure()
    {
      from ("file:/tmp/in2?noop=true")
       .log("Java DSL doing the heavy lifting")
       .to("file:/tmp/out2");
    }
}

And the Bundle Activator:

public class Activator implements BundleActivator {
    DefaultCamelContext camelContext;

    public void start(BundleContext context) {
        System.out.println("Starting the bundle");
        camelContext = new DefaultCamelContext();
        try {
            camelContext.setName("JavaDSLContext");
            camelContext.addRoutes(new FileRouter());
            camelContext.start();
        } catch (Exception ex) {
            System.out.println("Exception occured! " + ex.getMessage());
        }
    }

    public void stop(BundleContext context) {
        System.out.println("Stopping the bundle");
        if (camelContext != null) {
           try { 
              camelContext.stop();
           } catch (Exception ex) {
              System.out.println("Exception occured during stop context.");
           }
        }
    }   
}
Greg Fullard
  • 365
  • 3
  • 15
  • Is the java route deployed as a bundle? Or have you wrapped in some way? – Souciance Eqdam Rashti Oct 19 '16 at 07:40
  • 1
    By the way, I find the easiest way to work with Karaf and Camel is to use blueprint only connect the routeBuilder and then all the implementation is in the actual java route dsl. It makes it easy to connect Camel with Karaf. – Souciance Eqdam Rashti Oct 19 '16 at 07:42
  • It depends how your Java bundle is implemented. When you do this manually in OSGi you need to setup a bunch of stuff yourself, that you otherwise get for free with camel-blueprint, camel-cdi or camel-scr that all can run in OSGi. – Claus Ibsen Oct 19 '16 at 07:46
  • Thanks for the comments all. I'll put some more details in the original question. But in short: Yes, the route is configured in a bundle which configures the camelcontext in the activator. – Greg Fullard Oct 19 '16 at 10:44
  • After further exploration, I can now confirm that I'm deploying Jamie's code exactly: https://github.com/jgoodyear/ApacheKarafCookbook/tree/master/chapter2/chapter2-recipe3 and the same results occur. Route works, but is not listed by camel:route-list – Greg Fullard Oct 19 '16 at 14:35
  • Yes and that is your problem you create a DefaultCamelContext which is NOT OSGi based. See the source code of camel-scr to see how it setup OSGi with Camel. – Claus Ibsen Oct 20 '16 at 08:48

2 Answers2

1

Tx Souciance Eqdam Rashti. I worked through your blog this morning to see what you meant with using blueprint with JavaDSL.

Works like a charm.

Just for completeness sake, here's the change:

My Java Route class remains exactly the same as specified in the question, but I drop the Activator entirely, replacing it with a blueprint file.

The blueprint then looks like this:

<bean id="FileRouter" class="com.eightbitplatoon.learning.karaf.karafbasics.combined.FileRouter">
</bean>
<camelContext id="karafbasics-combined" xmlns="http://camel.apache.org/schema/blueprint">
    <routeBuilder ref="FileRouter" />
</camelContext>

Tx for the assistance!

Greg Fullard
  • 365
  • 3
  • 15
0

And thanks to Claus - I've worked through the material on Camel-SCR and eventually got that approach to work as well. My thinking is that Camel-SCR is probably the cleaner solution, because it makes it very easy to pass properties to the JavaDSL router.

Here's my final solution, for completeness' sake, then I'll close up this question: The file router now looks like this:

public class ScrFileRouter extends RouteBuilder {

    // Configured fields
    private String camelRouteId;

    @Override
    public void configure() throws Exception {
        // Add a bean to Camel context registry
        AbstractCamelRunner.getRegistry(getContext(), SimpleRegistry.class).put("testString", "this is a test");

        from("file:/tmp/in6?noop=true").routeId(camelRouteId)
        .to("file:/tmp/out6");
    }
}

And the SCR-based Camel runner looks like this:

@Component(label = ScrRunner.COMPONENT_LABEL, description = ScrRunner.COMPONENT_DESCRIPTION, immediate = true, metatype = true)
@Properties({
    @Property(name = "camelContextId", value = "scr-runner"),
    @Property(name = "camelRouteId", value = "scr-file-router"),
    @Property(name = "active", value = "true"),
})
@References({
    @Reference(name = "camelComponent",referenceInterface = ComponentResolver.class,
        cardinality = ReferenceCardinality.MANDATORY_MULTIPLE, policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY, bind = "gotCamelComponent", unbind = "lostCamelComponent")
})
public class ScrRunner extends AbstractCamelRunner {

    public static final String COMPONENT_LABEL = "ScrRunner";
    public static final String COMPONENT_DESCRIPTION = "This is the description for ScrRunner";

    @Override
    protected List<RoutesBuilder> getRouteBuilders() {
        List<RoutesBuilder> routesBuilders = new ArrayList<>();
        routesBuilders.add(new ScrFileRouter());
        return routesBuilders;
    }

    @Override
    protected void setupCamelContext(BundleContext bundleContext, String camelContextId)throws Exception{
        super.setupCamelContext(bundleContext, camelContextId);

        // Use MDC logging
        getContext().setUseMDCLogging(true);

        // Use breadcrumb logging
        getContext().setUseBreadcrumb(true);
    }
}

I followed the information on the Camel SCR website closely and almost got things working. Then I used the archetype proposed (camel-archetype-scr), which worked nicely.

So in the end I also had to make some changes to my POM file (Effectively just using the POM provided by the Archetype.)

Thanks to all for the assistance. I think I'll be able to get some traction now.

Cheers!

Greg Fullard
  • 365
  • 3
  • 15