I am using Apache Camel with SpringBoot to handle\process some data.
I was always thinking that exchange's properties can only be changed by fetching data from property via exchange.getProperty(..)
, processing data and setting new data into property via setProperty(..)
.
But now I see that my property in exchange is being changed while I am processing my fetched array.
Here is an example: I have an array of strings that I want to process (retain specific words from) in one property ("words" in sources) and another property ("retain" in sources) that holds a word that I want to replace.
I am fetching list of words into ArrayList<String>
and run method retainAll
to retain word I do not want. My idea is that original property in exchange will not be changed. But when I do run debug in unittest I can see that after retainAll(..)
method has finished not only local ArrayList<String>
is updated, but also property which holds all the words.
Am I overlooking something (wrongly using retainAll
method, maybe?) or is it a bug?
StringsProccessor.class:
package com.mydummytest;
import java.util.ArrayList;
import java.util.stream.Collectors;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class StringsProcessor implements Processor {
@SuppressWarnings("unchecked")
@Override
public void process(Exchange exchange) throws Exception {
ArrayList<String> input = (ArrayList<String>) exchange.getProperty("words");
String toRetain = (String) exchange.getProperty("retain");
input.retainAll(input.stream()
.filter(s -> s.equals(toRetain))
.collect(Collectors.toList())
);
}
}
StringsProcessorTest.class:
package com.mydummytest;
import java.util.ArrayList;
import java.util.Collections;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.impl.DefaultExchange;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class StringsProcessorTest {
private Exchange exchange;
private StringsProcessor proc;
@BeforeEach
void beforeEach() {
// camel classes
CamelContext ctx = new DefaultCamelContext();
exchange = new DefaultExchange(ctx);
proc = new StringsProcessor ();
ArrayList<String> words = new ArrayList<String>();
Collections.addAll(words, "fox", "racoon", "eagle", "salmon");
String retain = "salmon";
exchange.setProperty("words", words);
exchange.setProperty("retain", retain);
}
@Test
void testProcessing() throws Exception {
proc.process(exchange);
}
}