[
https://issues.apache.org/jira/browse/CAMEL-19346?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Max updated CAMEL-19346:
------------------------
Description:
First of all I have to apologize, cannot provide demo project to reproduce the
error. So, this is the issue:
using route something like this:
{code:java}
from(activemq..?consumerCount=5).bean(MyBean.class).to("http:foo.bar/url")
{code}
{code:java|title=application.yaml}
foo.base.url: http://foo.bar/foo
{code}
{code:java}
import org.apache.camel.builder.SimpleBuilder;
import static org.apache.camel.builder.Builder.simple;
public class MyBean {
public static final String PART1 = "{{foo.base.url}}";
public static final String PART2 = "$simple{header.fooId}"
public static final String FULL_URL = PART1 + "/" + PART2;
@Handler
public void process(Exchange exchange) {
var allInOne = simple(FULL_URL).evaluate(exchange, String.class);
var allInOneWithSB = SimpleBuilder.simple(FULL_URL).evaluate(exchange,
String.class);
var part1 = simple(PART1).evaluate(exchange, String.class);
var part2 = simple(PART2).evaluate(exchange, String.class);
var builtFromParts1 = part1 + "/" + message.getHeader("myId");
var builtFromParts2 = part1 + "/" + part2;
// at the same moment when allInOne is broken, other ones look good
message.setHeader(Exchange.HTTP_URI, allInOne); // sometimes broken
message.setHeader(Exchange.HTTP_URI, allInOneWithSB); // always correct
message.setHeader(Exchange.HTTP_URI, builtFromParts1); // always correct
message.setHeader(Exchange.HTTP_URI, builtFromParts2); // always correct
}{code}
The issue:
When {{MyBean}} is used in a single thread (1 queue consumer) everything works
fine.
When {{MyBean}} is used with multiple queue consumers after some time (about 50
messages with 5 consumers) starts messing up the Exchange.HTTP_URI value.
So instead of always having url like
{code:java}
http://foo.bar/foo/1
http://foo.bar/foo/2
...
http://foo.bar/foo/1024
{code}
we start getting weird results such as
{code:java}
http://foo.bar/foo/1
http://foo.bar/foo/http://foo.bar/foo/1
http://foo.bar/foo/11
{code}
After experimenting I suspect that the {{Builder.simple}} expression is not
thread safe or has some internal caching which causes the
{{{{{}expression{}}}}} to collide with $simple\{header.foo} when used together
in the same string.
So it takes the result of {{{{{}expression{}}}}} sets to some internal cache
then takes that value and adds the same value + result of ${simple\{header.foo}
When the expressions are evaluated separately Builder.simple() produces correct
result.
However, this issue never happened with deprecated SimpleBuilder.simple()
expression.
So even though {{allInOne}} was broken, other values such as
{{{}allInOneWithSB{}}}, {{{}builtFromParts1{}}}, {{builtFromParts2}} at the
same time were allways correct no matter how often and how many concurrent
consumers I used.
Update:
switched to \{{SimpleBuilder.simple}} and the same issue hit again. But calling
{{simple(expression).evaluate(exchange, String.class)}} twice seems to solve
the issue.
was:
First of all I have to apologize, cannot provide demo project to reproduce the
error. So, this is the issue:
using route something like this:
{code:java}
from(activemq..?consumerCount=5).bean(MyBean.class).to("http:foo.bar/url")
{code}
{code:java|title=application.yaml}
foo.base.url: http://foo.bar/foo
{code}
{code:java}
import org.apache.camel.builder.SimpleBuilder;
import static org.apache.camel.builder.Builder.simple;
public class MyBean {
public static final String PART1 = "{{foo.base.url}}";
public static final String PART2 = "$simple{header.fooId}"
public static final String FULL_URL = PART1 + "/" + PART2;
@Handler
public void process(Exchange exchange) {
var allInOne = simple(FULL_URL).evaluate(exchange, String.class);
var allInOneWithSB = SimpleBuilder.simple(FULL_URL).evaluate(exchange,
String.class);
var part1 = simple(PART1).evaluate(exchange, String.class);
var part2 = simple(PART2).evaluate(exchange, String.class);
var builtFromParts1 = part1 + "/" + message.getHeader("myId");
var builtFromParts2 = part1 + "/" + part2;
// at the same moment when allInOne is broken, other ones look good
message.setHeader(Exchange.HTTP_URI, allInOne); // sometimes broken
message.setHeader(Exchange.HTTP_URI, allInOneWithSB); // always correct
message.setHeader(Exchange.HTTP_URI, builtFromParts1); // always correct
message.setHeader(Exchange.HTTP_URI, builtFromParts2); // always correct
}{code}
The issue:
When {{MyBean}} is used in a single thread (1 queue consumer) everything works
fine.
When {{MyBean}} is used with multiple queue consumers after some time (about 50
messages with 5 consumers) starts messing up the Exchange.HTTP_URI value.
So instead of always having url like
{code:java}
http://foo.bar/foo/1
http://foo.bar/foo/2
...
http://foo.bar/foo/1024
{code}
we start getting weird results such as
{code:java}
http://foo.bar/foo/1
http://foo.bar/foo/http://foo.bar/foo/1
http://foo.bar/foo/11
{code}
After experimenting I suspect that the {{Builder.simple}} expression is not
thread safe or has some internal caching which causes the
{{\{\{expression\}\}}} to collide with $simple\{header.foo} when used together
in the same string.
So it takes the result of {{\{\{expression\}\}}} sets to some internal cache
then takes that value and adds the same value + result of ${simple\{header.foo}
When the expressions are evaluated separately Builder.simple() produces correct
result.
However, this issue never happened with deprecated SimpleBuilder.simple()
expression.
So even though {{allInOne}} was broken, other values such as
{{{}allInOneWithSB{}}}, {{{}builtFromParts1{}}}, {{builtFromParts2}} at the
same time were allways correct no matter how often and how many concurrent
consumers I used.
> Builder.simple expression is not thread safe
> --------------------------------------------
>
> Key: CAMEL-19346
> URL: https://issues.apache.org/jira/browse/CAMEL-19346
> Project: Camel
> Issue Type: Bug
> Components: came-core
> Affects Versions: 3.20.2, 3.20.3, 3.20.4
> Reporter: Max
> Priority: Major
>
> First of all I have to apologize, cannot provide demo project to reproduce
> the error. So, this is the issue:
> using route something like this:
> {code:java}
> from(activemq..?consumerCount=5).bean(MyBean.class).to("http:foo.bar/url")
> {code}
> {code:java|title=application.yaml}
> foo.base.url: http://foo.bar/foo
> {code}
> {code:java}
> import org.apache.camel.builder.SimpleBuilder;
> import static org.apache.camel.builder.Builder.simple;
> public class MyBean {
> public static final String PART1 = "{{foo.base.url}}";
> public static final String PART2 = "$simple{header.fooId}"
> public static final String FULL_URL = PART1 + "/" + PART2;
> @Handler
> public void process(Exchange exchange) {
> var allInOne = simple(FULL_URL).evaluate(exchange, String.class);
> var allInOneWithSB = SimpleBuilder.simple(FULL_URL).evaluate(exchange,
> String.class);
> var part1 = simple(PART1).evaluate(exchange, String.class);
> var part2 = simple(PART2).evaluate(exchange, String.class);
> var builtFromParts1 = part1 + "/" + message.getHeader("myId");
> var builtFromParts2 = part1 + "/" + part2;
> // at the same moment when allInOne is broken, other ones look good
> message.setHeader(Exchange.HTTP_URI, allInOne); // sometimes broken
> message.setHeader(Exchange.HTTP_URI, allInOneWithSB); // always correct
> message.setHeader(Exchange.HTTP_URI, builtFromParts1); // always correct
> message.setHeader(Exchange.HTTP_URI, builtFromParts2); // always correct
> }{code}
> The issue:
> When {{MyBean}} is used in a single thread (1 queue consumer) everything
> works fine.
> When {{MyBean}} is used with multiple queue consumers after some time (about
> 50 messages with 5 consumers) starts messing up the Exchange.HTTP_URI value.
> So instead of always having url like
> {code:java}
> http://foo.bar/foo/1
> http://foo.bar/foo/2
> ...
> http://foo.bar/foo/1024
> {code}
> we start getting weird results such as
> {code:java}
> http://foo.bar/foo/1
> http://foo.bar/foo/http://foo.bar/foo/1
> http://foo.bar/foo/11
> {code}
> After experimenting I suspect that the {{Builder.simple}} expression is not
> thread safe or has some internal caching which causes the
> {{{{{}expression{}}}}} to collide with $simple\{header.foo} when used
> together in the same string.
> So it takes the result of {{{{{}expression{}}}}} sets to some internal cache
> then takes that value and adds the same value + result of
> ${simple\{header.foo}
> When the expressions are evaluated separately Builder.simple() produces
> correct result.
> However, this issue never happened with deprecated SimpleBuilder.simple()
> expression.
> So even though {{allInOne}} was broken, other values such as
> {{{}allInOneWithSB{}}}, {{{}builtFromParts1{}}}, {{builtFromParts2}} at the
> same time were allways correct no matter how often and how many concurrent
> consumers I used.
>
> Update:
> switched to \{{SimpleBuilder.simple}} and the same issue hit again. But
> calling {{simple(expression).evaluate(exchange, String.class)}} twice seems
> to solve the issue.
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)