apache / camel-karavan

Apache Camel Karavan a Low-code Data Integration Platform
https://camel.apache.org
Apache License 2.0
388 stars 133 forks source link

Saga fails to compensate action. Throwing NullPointerException instead of calling compensation action. #1270

Closed dpalinic closed 1 month ago

dpalinic commented 1 month ago

Describe the bug

When part of the Saga step fails, compensating action should be called. Instead, NullPointerException is thrown. Demo project is attached.

Steps to reproduce the behavior

  1. Create an integration
  2. Create a Saga with 2 actions (e.g. createOrder and reserveCredit) and appropriate compensation actions (e.g. cancelOrder and refundCredit)
  3. Throw exception in reserveCredit action
  4. Observe NullPointerException is thrown instead of calling a compensation action. saga-demo.zip

Variant

Web Application

Container Management (if applicable)

None

Operating System (if applicable)

None

Version

4.4.0

Relevant log output

.camel.saga.InMemorySagaCoordinator : Cannot finalize compensation the saga
java.util.concurrent.CompletionException: java.lang.NullPointerException
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:315) ~[?:?]
    at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1194) ~[?:?]
    at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2309) ~[?:?]
    at org.apache.camel.saga.InMemorySagaCoordinator.doFinalize(InMemorySagaCoordinator.java:172) ~[camel-support-4.4.0.jar:4.4.0]
    at org.apache.camel.saga.InMemorySagaCoordinator.doCompensate(InMemorySagaCoordinator.java:151) ~[camel-support-4.4.0.jar:4.4.0]
    at org.apache.camel.saga.InMemorySagaCoordinator.compensate(InMemorySagaCoordinator.java:119) ~[camel-support-4.4.0.jar:4.4.0]
    at org.apache.camel.processor.saga.SagaProcessor.handleSagaCompletion(SagaProcessor.java:80) ~[camel-core-processor-4.4.0.jar:4.4.0]
    at org.apache.camel.processor.saga.RequiresNewSagaProcessor.lambda$process$0(RequiresNewSagaProcessor.java:48) ~[camel-core-processor-4.4.0.jar:4.4.0]
    at org.apache.camel.AsyncCallback.run(AsyncCallback.java:44) [camel-api-4.4.0.jar:4.4.0]
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.doRun(DefaultReactiveExecutor.java:199) [camel-base-engine-4.4.0.jar:4.4.0]
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.executeReactiveWork(DefaultReactiveExecutor.java:189) [camel-base-engine-4.4.0.jar:4.4.0]
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.tryExecuteReactiveWork(DefaultReactiveExecutor.java:166) [camel-base-engine-4.4.0.jar:4.4.0]
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148) [camel-base-engine-4.4.0.jar:4.4.0]
    at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59) [camel-base-engine-4.4.0.jar:4.4.0]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:163) [camel-core-processor-4.4.0.jar:4.4.0]
    at org.apache.camel.impl.engine.CamelInternalProcessor.processNonTransacted(CamelInternalProcessor.java:354) [camel-base-engine-4.4.0.jar:4.4.0]
    at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:330) [camel-base-engine-4.4.0.jar:4.4.0]
    at org.apache.camel.component.scheduler.SchedulerConsumer.sendTimerExchange(SchedulerConsumer.java:70) [camel-scheduler-4.4.0.jar:4.4.0]
    at org.apache.camel.component.scheduler.SchedulerConsumer.poll(SchedulerConsumer.java:50) [camel-scheduler-4.4.0.jar:4.4.0]
    at org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:204) [camel-support-4.4.0.jar:4.4.0]
    at org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:118) [camel-support-4.4.0.jar:4.4.0]
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
    at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
    at java.base/java.lang.Thread.run(Thread.java:840) [?:?]
Caused by: java.lang.NullPointerException
    at java.base/java.util.concurrent.CompletableFuture.screenExecutor(CompletableFuture.java:455) ~[?:?]
    at java.base/java.util.concurrent.CompletableFuture.supplyAsync(CompletableFuture.java:2005) ~[?:?]
    at org.apache.camel.saga.InMemorySagaCoordinator.doFinalize(InMemorySagaCoordinator.java:188) ~[camel-support-4.4.0.jar:4.4.0]
    at org.apache.camel.saga.InMemorySagaCoordinator.lambda$doFinalize$5(InMemorySagaCoordinator.java:173) ~[camel-support-4.4.0.jar:4.4.0]
    at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187) ~[?:?]
    ... 25 more
davsclaus commented 1 month ago

This is a general Apache Camel problem and not Karavan (Karavan is the UI designer).

You need to report these kind of "running Camel problems" to Camel itself https://camel.apache.org/community/support/

davsclaus commented 1 month ago

I created a ticket at Apache Camel JIRA for you https://issues.apache.org/jira/browse/CAMEL-20752

davsclaus commented 1 month ago

Okay so I have a fix in the works

2024-05-09 16:40:59.393 INFO 2150 --- [hread #7 - saga] saga-demo.camel.yaml:95 : Order cancelled!

Try as workaround to use

initMethod: start

in the InMemorySagaService bean

dpalinic commented 1 month ago

Thank you @davsclaus for a quick fix