Description
Hi Team,
we are using the Apache Camel LRA components within Java Springboot projects to implement saga services.
Till now, we are using Narayana as an LRA-Coordinator. Now we want to switch to Oracl MicroTX
(https://docs.oracle.com/en/database/oracle/transaction-manager-for-microservices/24.2/tmmdg/lra-transaction-protocol.html).
After configuring Oracle MircoTX instead of Narayana, we are facing two problems within the
Apache Camel LRA component code.
1) While joining an LRA Transaction, the payload sent by Apache Camel is URL encoded
2) The Query parameter sent by Oracle LRA coordinator are url encoded, but will not be decoded by Apache Camal LRA (see also: CAMEL-21197)
I will set up a branch with my suggested code changes and link this afterwards to this jira bug.
The code changes are completely backwards compatible with Narayana (already tested).
1) Joining an LRA Transaction
The class 'LRAClient' is using 'LRAUrlBuilder' inside Method 'join'. All parts of the http put body are url encoded.
Within Oracle LRA Coordinator log i can see the incomming request from Apache Camel:
<https://k5-mmeeasysaga.qa-servicebuilder-dev.svc.cluster.local/camel/compensate?Camel-Saga-Complete=direct%3A%2F%2Fsaga1_sagaService_complete>; rel=compensate,<https://k5-mmeeasysaga.qa-servicebuilder-dev.svc.cluster.local/camel/complete?Camel-Saga-Complete=direct%3A%2F%2Fsaga1_sagaService_complete>; rel=complete
This url encoded query param 'Camel-Saga-Complete=direct%3A%2F%2Fsaga1_sagaService_complete' will be encoded again on Oracle LRA Coordinator side.
This is causing the error message within Apache Camel LRA:
o.a.c.RuntimeCamelException: Cannot join LRA at o.a.c.s.l.LRAClient.lambda$join$2(LRAClient.java:138) ... 10 common frames omitted Wrapped by: j.u.c.CompletionException: org.apache.camel.RuntimeCamelException: Cannot join LRA at j.u.c.CompletableFuture.encodeThrowable(Unknown Source) at j.u.c.CompletableFuture.completeThrowable(Unknown Source) at j.u.c.CompletableFuture$UniApply.tryFire(Unknown Source) at j.u.c.CompletableFuture.postComplete(Unknown Source) at j.u.c.CompletableFuture.postFire(Unknown Source) at j.u.c.CompletableFuture$UniWhenComplete.tryFire(Unknown Source) at j.u.c.CompletableFuture$Completion.exec(Unknown Source) at j.u.c.ForkJoinTask.doExec(Unknown Source) at j.u.c.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source) at j.u.c.ForkJoinPool.scan(Unknown Source) at j.u.c.ForkJoinPool.runWorker(Unknown Source) at j.u.c.ForkJoinWorkerThread.run(Unknown Source)
When logging the result http code and body
LOG.error("error while joining LRA: {} / {}", response.statusCode(), response.body());
i am getting this:
error while joining LRA: 400 / error: URL is double encoded
The problem can be solved by not url encoding the given urls within the joinLRA payload.
org.apache.camel.service.lra.LRAUrlBuilder -> query:
This code should not be executed:
key = URLEncoder.encode(toNonnullString(key), StandardCharsets.UTF_8.name()); value = URLEncoder.encode(toNonnullString(value), StandardCharsets.UTF_8.name());
2) Decode given query parameter from Oracle LRA-Coordinator call
After solving 1), i am getting a new exception:
j.l.IllegalArgumentException: URI direct%3A%2F%2Fsaga1_sagaService_complete is not allowed at o.a.c.s.l.LRASagaRoutes.verifyRequest(LRASagaRoutes.java:107) at o.a.c.s.p.DelegateSyncProcessor.process(DelegateSyncProcessor.java:65) at o.a.c.p.e.RedeliveryErrorHandler$SimpleTask.handleFirst(RedeliveryErrorHandler.java:440) at o.a.c.p.e.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:416) at o.a.c.i.e.DefaultReactiveExecutor$Worker.doRun(DefaultReactiveExecutor.java:199) at o.a.c.i.e.DefaultReactiveExecutor$Worker.executeReactiveWork(DefaultReactiveExecutor.java:189) at o.a.c.i.e.DefaultReactiveExecutor$Worker.tryExecuteReactiveWork(DefaultReactiveExecutor.java:166) at o.a.c.i.e.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148) at o.a.c.i.e.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59) at o.a.c.p.Pipeline.process(Pipeline.java:163) at o.a.c.i.e.CamelInternalProcessor.processNonTransacted(CamelInternalProcessor.java:346) at o.a.c.i.e.CamelInternalProcessor.process(CamelInternalProcessor.java:322) at o.a.c.i.e.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:82) at o.a.c.s.AsyncProcessorSupport.process(AsyncProcessorSupport.java:32) at o.a.c.h.c.CamelServlet.doExecute(CamelServlet.java:313) at o.a.c.h.c.CamelServlet.doService(CamelServlet.java:235) at o.a.c.h.c.CamelServlet.handleService(CamelServlet.java:111) at o.a.c.h.c.CamelServlet.service(CamelServlet.java:97) at j.s.h.HttpServlet.service(HttpServlet.java:614) ... 5 frames excluded at k.s.s.s.c.SagaContextFilter.doFilterInternal(SagaContextFilter.java:52) ... 4 frames excluded at o.s.s.w.FilterChainProxy.lambda$doFilterInternal$3(FilterChainProxy.java:231) at o.s.s.w.ObservationFilterChainDecorator$FilterObservation$SimpleFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:479) at o.s.s.w.ObservationFilterChainDecorator$AroundFilterObservation$SimpleAroundFilterObservation.lambda$wrap$1(ObservationFilterChainDecorator.java:340) at o.s.s.w.ObservationFilterChainDecorator.lambda$wrapSecured$0(ObservationFilterChainDecorator.java:82) ... 2 frames excluded at o.s.s.w.ObservationFilterChainDecorator$ObservationFilter.wrapFilter(ObservationFilterChainDecorator.java:240) ... 110 frames truncated
After finalizing the saga, the Oracle LRA-Coordinator is calling the 'onComplete' for all participants and the service.
PUT /camel/complete?Camel-Saga-Compensate=direct%3A%2F%2Fsaga1_participant1_compensate&Camel-Saga-Complete=direct%3A%2F%2Fsaga1_participant1_complete
Within o.a.c.s.l.LRASagaRoutes.verifyRequest(LRASagaRoutes.java:107) the extracted query param 'Camel-Saga-Compensate' is still url encoded:
direct%3A%2F%2Fsaga1_sagaService_complete
Therefore the check within LRASagaRoutes.verifyRequest fails, because the valid (indexed) uri is
direct://saga1_sagaService_complete
The problem can completely solved by CAMEL-21197. In the meantime in will provide a suggestion for an workaround.
best regards
Dirk
Attachments
Issue Links
- relates to
-
CAMEL-21197 URISupport.parseQuery is not decoding correctly
- Resolved
- links to