Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to kick off a camel route using a java interface or bean?

I'd like to setup a spring bean (either via interface or bean class). that I can call to "start" a Route.

In this simple example when I call sayHello("world") from code I'd like it to route the return value of the sayHello method the endpoint that will write it out to a file.

Does anyone know if this is possible, or how to go about this? I know I can expose that same interface via CXF and make this work, but I really just want to call a method, not go through the trouble of sending a jms message or calling a webservice.

public interface Hello{
   public String sayHello(String value);
}

from("bean:helloBean").to("file:/data/outbox?fileName=hello.txt");
like image 939
ScArcher2 Avatar asked Jul 29 '10 19:07

ScArcher2


People also ask

How do you stop a Camel route in Java?

The best practice for stopping a route from a route, is to either: signal to another thread to stop the route. spin off a new thread to stop the route.

How do you start a Camel route?

To create a route in Camel, you first define it in code. This is called a route definition, and it is usually written in Java or XML. Then, you start Camel, passing it your route definition. Camel reads the route definition and creates the route inside the Camel Context.

What is Bean in Apache Camel?

The Bean EIP is used for invoking a method on a bean, and the returned value is the new message body. The Bean EIP is similar to the Bean component which also is used for invoking beans, but in the form as a Camel component.

Is a Camel a Java?

Apache Camel ™ is a versatile open-source integration framework based on known Enterprise Integration Patterns. Camel empowers you to define routing and mediation rules in a variety of domain-specific languages (DSL, such as Java, XML, Groovy, Kotlin, and YAML).


3 Answers

You can use ProducerTemplate:

import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

@Component
public class HelloImpl implements Hello {

    @Produce(uri = "direct:start")
    private ProducerTemplate template;

    @Override
    public Object sayHello(String value) throws ExecutionException, InterruptedException {
        Future future = template.asyncSendBody(template.getDefaultEndpoint(), value);
        return future.get();
    }
}

and your camel route should looks like:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.mycompany.camel"/>

    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="direct:start"/>
            <to uri="log:com.mycompany.camel?level=DEBUG"/>
        </route>
    </camelContext>

</beans>
like image 88
mokshino Avatar answered Oct 27 '22 02:10

mokshino


Yes you can use proxy/remoting in Camel to do this.

Then when you invoke sayHello(value) the value is being routed to the chosen route. And the reply from the route is returned from the sayHello method.

See these links
- http://camel.apache.org/spring-remoting.html
- http://camel.apache.org/hiding-middleware.html
- http://camel.apache.org/using-camelproxy.html

Chapter 14 of the Camel in Action book covers this in much more detail: http://www.manning.com/ibsen

like image 10
Claus Ibsen Avatar answered Oct 27 '22 01:10

Claus Ibsen


I need to look into Claus' answers, but for a quick and dirty UI I went with a different approach.

I was using Spring MVC 3.1.X and have an admin console for various items in my application. I wrote a Controller to display the routes and their statuses, as well as provided links to start and stop the routes as needed. Here's some of the code:

@Controller
public class CamelController {
    private static final Log LOG = LogFactory.getLog(CamelController.class);

    @Autowired
    @Qualifier("myCamelContextID")
    private CamelContext camelContext;

    @RequestMapping(value = "/dashboard", method = RequestMethod.GET)
    public String dashboard(Model model) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("camel context is suspended : " + camelContext.isSuspended());
        }

        List<Route> routes = camelContext.getRoutes();
        List<RouteStatus> routeStatuses = new ArrayList<RouteStatus>();
        for (Route r : routes) {
            RouteStatus rs = new RouteStatus();
            rs.setId(r.getId());
            rs.setServiceStatus(camelContext.getRouteStatus(r.getId()));
            routeStatuses.add(rs);
        }

        model.addAttribute("routeStatuses", routeStatuses);

        return "dashboard";
    }

    @RequestMapping(value = "/dashboard/{routeId}/start", method = RequestMethod.GET)
    public String startRoute(@PathVariable String routeId) {
        try {
            camelContext.startRoute(routeId);
            if (LOG.isDebugEnabled()) {
                LOG.debug("camel context is starting route [" + routeId + "]");
            }
        } catch (Exception e) {
            LOG.error("failed to start camel context [" + camelContext + "]");
        }

        return "redirect:/dashboard";
     }

    @RequestMapping(value = "/dashboard/{routeId}/stop", method = RequestMethod.GET)
    public String stopRoute(@PathVariable String routeId) {
        try {
            camelContext.stopRoute(routeId);
            if (LOG.isDebugEnabled()) {
                LOG.debug("camel context is stopping route [" + routeId + "]");
            }
        } catch (Exception e) {
            LOG.error("failed to stop camel context [" + camelContext + "]");
        }
        return "redirect:/dashboard";
        }
    }
}

There's a little POJO I made to go with it:

public class RouteStatus {
    private String id;
    private ServiceStatus serviceStatus;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public ServiceStatus getServiceStatus() {
        return serviceStatus;
    }

    public void setServiceStatus(ServiceStatus serviceStatus) {
        this.serviceStatus = serviceStatus;
    }
}
like image 2
Greg Avatar answered Oct 27 '22 03:10

Greg