是否可以使用 java 接口或 bean 启动骆驼路线?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3366052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 22:37:24  来源:igfitidea点击:

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

javaapache-camel

提问by ScArcher2

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

我想设置一个 spring bean(通过接口或 bean 类)。我可以调用它来“启动”一条路线。

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.

在这个简单的示例中,当我从代码中调用 sayHello("world") 时,我希望它将 sayHello 方法的返回值路由到将其写入文件的端点。

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.

有谁知道这是否可能,或者如何解决这个问题?我知道我可以通过 CXF 公开相同的接口并使其工作,但我真的只想调用一个方法,而不是通过发送 jms 消息或调用 web 服务的麻烦。

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

from("bean:helloBean").to("file:/data/outbox?fileName=hello.txt");

采纳答案by Claus Ibsen

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

是的,您可以在 Camel 中使用代理/远程处理来执行此操作。

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.

然后,当您调用 sayHello(value) 时,该值将被路由到所选路由。来自路由的回复是从 sayHello 方法返回的。

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

请参阅这些链接
- 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

Camel in Action 一书的第 14 章更详细地介绍了这一点:http: //www.manning.com/ibsen

回答by Greg

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

我需要查看 Claus 的答案,但是对于快速而肮脏的 UI,我采用了不同的方法。

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:

我使用的是 Spring MVC 3.1.X,并且在我的应用程序中有一个管理各种项目的管理控制台。我编写了一个控制器来显示路线及其状态,并提供了根据需要启动和停止路线的链接。这是一些代码:

@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:

我做了一个小 POJO 来配合它:

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;
    }
}

回答by mokshino

You can use ProducerTemplate:

您可以使用 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>

回答by Yogesh

Since my routes were spring components using CamelConfiguration. I did following to use my interface in camel routes.

由于我的路线是使用CamelConfiguration 的弹簧组件。我做了以下在骆驼路线中使用我的界面。

@Component
public class SomeRoute extends RouteBuilder {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void configure() throws Exception {
        from("direct:someroute")
        .bean(applicationContext.getBean(SomeInterface.class).getClass(), "someAbstractMethod")
        .to("direct:otherroute");
    }
}

This was very straight case, if you have multiple beans using same interface or abstract class you probably have to do some logic before using .getClass()on bean.

这是非常直接的情况,如果您有多个 bean 使用相同的接口或抽象类,您可能必须在使用.getClass()bean之前做一些逻辑。

回答by Alpar

None of the other answered worked for me, they all built and were valid, but the routes did not trigger.

其他答案都不适合我,它们都已构建且有效,但路由未触发。

This is the solution that I ended up using:

这是我最终使用的解决方案:

import org.apache.camel.Handler;

public class Hello{

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

   @Handler   
   public void sayHello() {
       producer.sendBody("hello")
   }
}

from("timer:hubspotContacts?repeatCount=1").bean(Hello.class);
from("direct:start").to("log:hello");
  • The timercomponent from the first route was the key missing part for me. With repeatCount=1it triggers exactly once, on startup and causes the bean method to be called. It also support a call rate or delay if you need the method to be called multiple times.
  • the @Handlerannotations serves as a marker so the method name doesn't have to be made explicit in the route configuration
  • the directcomponent connects the producer with it's consumers
  • 第一条路线的计时器组件对我来说是关键的缺失部分。有了repeatCount=1它触发正好一次,在启动时并导致被称为bean的方法。如果您需要多次调用该方法,它还支持调用率或延迟。
  • @Handler注释作为标记,以便方法的名称没有在路由配置进行明确
  • 直接组件生产商与它的消费者连接