[英]Registering listeners of an Apache Camel Processor
我嘗試將在 Apache Camel 處理器中處理的數據推送到監聽器 class。 在處理器 class 實例中,我嘗試在 Camel 上下文的實例化期間注冊偵聽器,但不知何故失敗了。 也許我在這里根本就錯了,這是不可能的。 如果是這種情況,如果你告訴我就好了。
I have an Apache Camel route fetching JSON messages from an ActiveMQ server and pushing these JSONs to a custom processor class, defined in Camel-Spring XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="url to ActiveMQ" />
<property name="clientID" value="clientID" />
<property name="userName" value="theUser" />
<property name="password" value="thePassword" />
</bean>
<bean id="pooledConnectionFactory" class="org.apache.activemq.jms.pool.PooledConnectionFactory"
init-method="start" destroy-method="stop">
<property name="maxConnections" value="8" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="pooledConnectionFactory" />
</bean>
<bean id="customProcessor" class="...CustomProcessorClass" />
<camelContext id="matrixProfileContext" xmlns="http://camel.apache.org/schema/spring">
<route id="matrixProfileRoute" autoStartup="false">
<from uri="activemq:queue:queuename" />
<log message="${body}" />
<to uri="customProcessor" />
</route>
</camelContext>
</beans>
我的想法是 class CustomProcessor 解組通過路由傳遞的 JSON 內容並將 POJO 推送到實現偵聽器接口的偵聽器 class :
public interface ProcessorListenerIF {
public void doOnDataProcessed(POJO processedData);
}
我通過單元測試測試整個設置:
public class TestProcessor extends TestCase {
@Test
public void testRoute() throws Exception {
MyActiveMQConnector camelContext = new MyActiveMQConnector(new TestListener());
try {
camelContext.startConnections();
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
} finally {
camelContext.stopConnection();
}
}
private class TestListener implements ProcessorListenerIF {
@Override
public void doOnDataProcessed(POJO data) {
System.out.println(data);
}
}
}
駱駝處理器有兩種方法:
public void addListener(MatrixProfileProcessorListenerIF listener) {
_processorListeners.add(listener);
}
@Override
public void process(Exchange exchange) throws Exception {
Pseudocode: POJO data = unmarshal_by_JSON-JAVA(exchange)
_processorListeners.parallelStream().forEach(listener -> {
listener.doOnDataProcessed(data);
});
}
我在 ActiveMQConnector 的構造函數中注冊監聽器:
public class ActiveMQConnector {
private SpringCamelContext _camelContext = null;
public ActiveMQConnector(ProcessorListenerIF listener) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("camelContext.xml");
_camelContext = new SpringCamelContext(appContext);
-------------------------------------
((CustomProcessor) _camelContext.getProcessor("customProcessor")).addListener(listener);
-------------------------------------
}
public void startConnections() throws Exception {
try {
_camelContext.start();
} catch (Exception e) {
exception handling
}
}
... more methods
上面突出顯示的 ((CustomProcessor)... 行失敗:語句_camelContext.getProcessor
沒有找到任何內容,實例_camelContext
中的路由為空。
我怎樣才能實現將處理后的數據從處理器推送到某個觀察者?
我找到了另一種解決方案,它完全基於 Java 而沒有 Spring XML。
單元測試仍然像上面那樣。 我沒有通過 Spring XML 定義 ActiveMQEndpoint,而是創建了一個新的 class:
public class MyActiveMQConnection {
public static ActiveMQConnectionFactory createActiveMQConnectionFactory() {
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
connectionFactory.setBrokerURL("tcp://<activemq-url>:<port>");
connectionFactory.setUserName("myUsername");
// connection factory configuration:
connectionFactory.setUseAsyncSend(false);
connectionFactory.setClientID(UUID.randomUUID().toString());
connectionFactory.setConnectResponseTimeout(300);
... whatever ...
return connectionFactory;
}
}
此外,我更改了 class ActiveMQConnector
的構造函數:
public ActiveMQConnector(ProcessorListenerIF listener) throws Exception {
_camelContext = new DefaultCamelContext();
_camelContext.addComponent("activemqEndpoint",
JmsComponent.jmsComponent(MyActiveMQConnection.createActiveMQConnectionFactory()));
_camelContext.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
MyCustomProcessor processor = MyCustomProcessor.getInstance();
processor.addListener(listener);
from("activemqEndpoint:queue:matrixprofile") //
.process(processor) //
.to("stream:out");
}
});
}
我將處理器實現為 singleton 看起來像這樣(為了完整性):
public class MyCustomProcessor implements Processor {
private final Set<ProcessorListenerIF> _processorListeners = new HashSet<>();
private static volatile MyCustomProcessor _myInstance = null;
private static Object _token = new Object();
private MyCustomProcessor() {
}
public static MyCustomProcessor getInstance() {
MyCustomProcessor result = _myInstance;
if (result == null) {
synchronized (_token) {
result = _myInstance;
if (result == null)
_myInstance = result = new MyCustomProcessor();
}
}
return result;
}
public void addListener(ProcessorListenerIF listener) {
_processorListeners.add(listener);
}
/**
* I assume the JSON has the following structure:
* {timestamp: long, data: double[]}
**/
@Override
public void process(Exchange exchange) throws Exception {
_processorListeners.parallelStream().forEach(listener -> {
// convert incoming message body to json object assuming data structure above
JSONObject jsonObject = new JSONObject(exchange.getMessage().getBody().toString());
MyPOJO myPojo = new MyPOJO();
try {
myPojo.setTimestamp(jsonObject.getLong("timestamp"));
} catch (Exception e) {
...
}
try {
JSONArray dataArray = jsonObject.getJSONArray("data");
double[] data = new double[dataArray.length()];
for (int i = 0; i < dataArray.length(); i++) {
data[i] = Double.valueOf(dataArray.get(i).toString());
}
myPojo.setData(data);
} catch (Exception e) {
...
}
listener.doOnDataProcessed(myPojo);
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.