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

Posted

技术标签:

【中文标题】是否可以使用 java 接口或 bean 启动骆驼路线?【英文标题】:Is it possible to kick off a camel route using a java interface or bean? 【发布时间】:2011-03-22 22:01:13 【问题描述】:

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

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

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

public interface Hello
   public String sayHello(String value);


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

【问题讨论】:

【参考方案1】:

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

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

查看这些链接 - http://camel.apache.org/spring-remoting.html - http://camel.apache.org/hiding-middleware.html -http://camel.apache.org/using-camelproxy.html

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

【讨论】:

感谢您回答我的问题。我想我需要更新我的 MEAP 书。对于第 14 章,它说 TBD。不过这本书很有帮助!【参考方案2】:

我需要查看克劳斯的答案,但为了获得快速而肮脏的 UI,我采用了不同的方法。

我使用的是 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";
        
    

我做了一个小 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;
    

【讨论】:

【参考方案3】:

你可以使用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();
    

你的骆驼路线应该是这样的:

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

【讨论】:

【参考方案4】:

因为我的路线是使用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");
    

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

【讨论】:

【参考方案5】:

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

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

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");
第一条路线中的timer 组件是我缺少的关键部分。使用repeatCount=1,它只会在启动时触发一次,并导致调用 bean 方法。如果您需要多次调用该方法,它还支持调用速率或延迟。 @Handler 注释用作标记,因此方法名称不必在路由配置中明确说明 direct 组件将生产者与其消费者连接起来

【讨论】:

以上是关于是否可以使用 java 接口或 bean 启动骆驼路线?的主要内容,如果未能解决你的问题,请参考以下文章

Spring启动流程

JAVA中的Bean是指啥

.net 中的 Apache 骆驼替代品?

骆驼路线测试:找不到适合属性的设置器:

Spring BootSpring Boot之使用ImportBeanDefinitionRegistrar类实现动态注册Bean

骆驼:从另一个途径调用一个途径,并同步得到响应。