2016-12-20 4 views
0

Я использую Camel в Karaf используя SCR для обработки сообщений от ActiveMQCamel SCR компонент пытается добавить компонент в контексте дважды, если маршрут строитель включает ErrorHandler

Версии:

  • Camel: 2.16.0
  • Karaf: 4.0.7
  • ActiveMQ 5.14.1

Когда я раскрываю следующий верблюд маршрут к Karaf все работает отлично:

package com.test; 
import org.apache.camel.builder.RouteBuilder; 

public class TestRoute extends RouteBuilder { 
    @Override 
    public void configure() throws Exception { 

     from("activemq:queue:TEST.IN") 
     .routeId("test-route") 
     .log("Message picked up from IN queue"); 
    } 
} 

Вот мой SCR Runner класс:

package com.test; 

import java.util.ArrayList; 
import java.util.List; 

import org.apache.activemq.ActiveMQConnectionFactory; 
import org.apache.activemq.camel.component.ActiveMQComponent; 
import org.apache.activemq.pool.PooledConnectionFactory; 
import org.apache.camel.RoutesBuilder; 
import org.apache.camel.component.jms.JmsConfiguration; 
import org.apache.camel.scr.AbstractCamelRunner; 
import org.apache.camel.spi.ComponentResolver; 
import org.apache.felix.scr.annotations.Component; 
import org.apache.felix.scr.annotations.Properties; 
import org.apache.felix.scr.annotations.Property; 
import org.apache.felix.scr.annotations.Reference; 
import org.apache.felix.scr.annotations.ReferenceCardinality; 
import org.apache.felix.scr.annotations.ReferencePolicy; 
import org.apache.felix.scr.annotations.ReferencePolicyOption; 
import org.apache.felix.scr.annotations.References; 
import org.osgi.framework.BundleContext; 

@Component(label = TestRunner.COMPONENT_LABEL, description = TestRunner.COMPONENT_DESCRIPTION, immediate = true, metatype = true) 
@Properties({ 
    @Property(name = "camelContextId", value = "test-context"), 
    @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 TestRunner extends AbstractCamelRunner { 

    public static final String COMPONENT_LABEL = "TestRunner"; 
    public static final String COMPONENT_DESCRIPTION = "This is the description for the test runner"; 

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

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

     // Add Active MQ connection factory 
     ActiveMQConnectionFactory amqConnectionFactory = new ActiveMQConnectionFactory("tcp://c3m-activemq:61616"); 
     amqConnectionFactory.setUserName("admin"); 
     amqConnectionFactory.setPassword("admin"); 

     // Create Pooled Connection Factory 
     PooledConnectionFactory amqPooledConnectionFactory = new PooledConnectionFactory(amqConnectionFactory); 
     amqPooledConnectionFactory.setMaxConnections(5); 
     amqPooledConnectionFactory.setMaximumActiveSessionPerConnection(5); 

     // Create JMS Configuration 
     JmsConfiguration consumerJmsConfig = new JmsConfiguration(amqPooledConnectionFactory); 
     consumerJmsConfig.setConcurrentConsumers(5); 

     // Create the ActiveMQ Component 
     ActiveMQComponent activemq = ActiveMQComponent.activeMQComponent(); 
     activemq.setConfiguration(consumerJmsConfig); 

     // Add activeMQ component to the Camel Context 
     getContext().addComponent("activemq", activemq);    

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

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

Однако, если добавить ErrorHandler к моему routeBuilder тогда все терпят неудачу.

Вот тот же маршрут с ErrorHandler добавил:

public void configure() throws Exception { 
    errorHandler(deadLetterChannel("activemq:queue:TEST.DLQ").useOriginalMessage()); 

    from("activemq:queue:TEST.IN") 
    .routeId("test-route") 
    .log("Message picked up from IN queue"); 
} 

Что происходит: - При установке узелок на Karaf дается следующее сообщение об ошибке:

2016-12-20 09:49: 58,248 | ОШИБКА | пользователя nsole karaf | маршрутизатор | 124 - com.test.router - 1.1.0.SNAPSHOT | [com.test.TestRunner (7)] Метод активизации выбрал исключение java.lang.IllegalArgumentException: не удается добавить компонент как уже добавленный ранее: activemq at org.apache.camel.impl.DefaultCamelContext.addComponent (DefaultCamelContext. java: 369) at com.test.TestRunner.setupCamelContext (TestRunner.java:75) [124: com.test.router: 1.1.0.SNAPSHOT] at org.apache.camel.scr.AbstractCamelRunner.prepare (AbstractCamelRunner .java: 90) [72: org.apache.camel.camel-scr: 2.16.0] at org.apache.camel.scr.AbstractCamelRunner.activate (AbstractCamelRunner.java:79) [72: org.apache.camel .camel-scr: 2.16.0] ...

И затем маршрут верблюда НЕ развернут в Карафе.

Я проследовать с некоторыми более поиска неисправностей, но, возможно, кто-то более полно понять, что происходит не так здесь

ответ

0

В вашем собственном TestRunner классе только тогда добавить компонент, если он еще не зарегистрирован, то вы можете использовать

if (context.hasComponent("activemq") != null) { 
    ... add component 
} 
+0

Я попробовал нечто подобное раньше (а затем также использовал ваш конкретный код), но результат тот же. –

+0

И интересно, когда я следую этому подходу (добавив компонент условно), и я прокомментирую ошибкуHandler, я получаю следующую ошибку, когда начинается маршрут верблюда 2016-12-20 10: 58: 30,325 | ОШИБКА | onsumer [TEST.IN] | faultJmsMessageListenerContainer | 102 - org.apache.servicemix.bundles.spring-jms - 3.2.17.RELEASE_1 | Не удалось обновить JMS Connection для адресата TEST.IN - повторить попытку в 5000 мс. Причина. Имя пользователя [null] или пароль недействительны. ... Не уверен, что мне не хватает –

0

В конце концов я решил проблему со следующим взломом: если компонент уже существует, я сначала удаляю его, а затем добавляю обратно.

Вот код:

// If activemq component already exists, remove it 
// Note: This is a bit of a hack, but if we keep the one that is there 
// Camel throws a security exception. 
if (getContext().hasComponent("activemq") != null) { 
    getContext().removeComponent("activemq"); 
} 

// Create the ActiveMQ Component 
ActiveMQComponent activemq = ActiveMQComponent.activeMQComponent(); 
activemq.setConfiguration(consumerJmsConfig); 
getContext().addComponent("activemq", activemq); 

Не очень, но если я не удалить его, и развернуть маршрут, верблюд дает исключение безопасности, почти как если существующий компонент «потерял» полномочия брокер.

Спасибо за помощь. Клаус!