camunda-community-hub / camunda-platform-7-camel

Community Extension to add Apache Camel support for Camunda Platform 7
Apache License 2.0
82 stars 57 forks source link

Stop camunda 'route' on camel exception. #49

Open lsattem opened 5 years ago

lsattem commented 5 years ago

Hi! I have tried googling around for a solution to this, but I've not found anything so far.

I'm sending data from Camel to Camunda via camunda-bpm://start?.... At several points it calls Camel endpoints, such as ${camel.sendTo('direct:debug')}. However, when any of these Camel routes/endpoints throw an exception, the Camunda route proceeds as if nothing wrong has occurred. This will cause issues later in the Camunda route. Setting an 'exception' variable and checking for it after every call to Camel will make the BPMN extremely bloated real quick.

So, in short: Is it possible to cancel a Camunda 'route/run' when one of its calls to Camel throws an exception?

berndruecker commented 5 years ago

How did you configure the route? See this example where I map Exceptions to a BPMN Error, so I can use it there:

https://github.com/camunda-consulting/code/blob/master/one-time-examples/camel-use-cases/src/main/java/org/camunda/demo/camel/MyCamelRouteBuilder.java#L62

Or do you want to create an incident in Camunda?

lsattem commented 5 years ago

Hi. Thanks for your quick response.

I made a quick example below displaying my issue. I have two processes in my BPMN. I want Camunda not to run/enter the second process if the first process (a call to camel) throws an exception. I have tried appending the code in your example (adding the onException-snippet to one route, both routes and making it global; also tried to add 'route stop' to the onException clause). It still calls the second process and prints "Got here. Shouldn't have".

Java code:

@Component
public class TestRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("timer://foo?period=60000")
                .to(ExchangePattern.InOut, "camunda-bpm://start?processDefinitionKey=TinyTest")
                .process(exchange -> {

                });

        from("direct:throwException")
                .process(exchange -> {
                    System.out.println("Throwing exception!");
                    throw new Exception("This is a test.");
                });

        from("direct:shouldNotGetHere")
                .process(exchange -> {
                    System.out.println("Got here. Shouldn't have.");
                });
    }
}

BPMN: Screenshot from 2019-03-21 13-37-58

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_0xu35vu" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="2.2.4">
  <bpmn:collaboration id="Collaboration_15s8lba">
    <bpmn:participant id="Participant_1ok1ye0" name="Test Process" processRef="TinyTest" />
  </bpmn:collaboration>
  <bpmn:process id="TinyTest" isExecutable="true">
    <bpmn:scriptTask id="ScriptTask_0gsg11r">
      <bpmn:incoming>SequenceFlow_1gf46wy</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_0xsf06d</bpmn:outgoing>
      <bpmn:script>${camel.sendTo('direct:shouldNotGetHere')}</bpmn:script>
    </bpmn:scriptTask>
    <bpmn:endEvent id="EndEvent_13hia8w">
      <bpmn:incoming>SequenceFlow_0xsf06d</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="SequenceFlow_0xsf06d" sourceRef="ScriptTask_0gsg11r" targetRef="EndEvent_13hia8w" />
    <bpmn:sequenceFlow id="SequenceFlow_1gf46wy" sourceRef="Task_04hdes9" targetRef="ScriptTask_0gsg11r" />
    <bpmn:sequenceFlow id="SequenceFlow_1ed8fby" sourceRef="StartEvent_1" targetRef="Task_04hdes9" />
    <bpmn:scriptTask id="Task_04hdes9">
      <bpmn:incoming>SequenceFlow_1ed8fby</bpmn:incoming>
      <bpmn:outgoing>SequenceFlow_1gf46wy</bpmn:outgoing>
      <bpmn:script>${camel.sendTo('direct:throwException')}</bpmn:script>
    </bpmn:scriptTask>
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>SequenceFlow_1ed8fby</bpmn:outgoing>
    </bpmn:startEvent>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_15s8lba">
      <bpmndi:BPMNShape id="Participant_1ok1ye0_di" bpmnElement="Participant_1ok1ye0">
        <dc:Bounds x="145" y="126" width="696" height="250" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="195" y="168" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="ScriptTask_08xdegd_di" bpmnElement="Task_04hdes9">
        <dc:Bounds x="340" y="146" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="ScriptTask_0gsg11r_di" bpmnElement="ScriptTask_0gsg11r">
        <dc:Bounds x="543" y="146" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="EndEvent_13hia8w_di" bpmnElement="EndEvent_13hia8w">
        <dc:Bounds x="785" y="168" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="SequenceFlow_0xsf06d_di" bpmnElement="SequenceFlow_0xsf06d">
        <di:waypoint x="643" y="186" />
        <di:waypoint x="785" y="186" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="SequenceFlow_1gf46wy_di" bpmnElement="SequenceFlow_1gf46wy">
        <di:waypoint x="440" y="186" />
        <di:waypoint x="543" y="186" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="SequenceFlow_1ed8fby_di" bpmnElement="SequenceFlow_1ed8fby">
        <di:waypoint x="231" y="186" />
        <di:waypoint x="340" y="186" />
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>
lsattem commented 5 years ago

Is there something wrong with my solution? Or have I misunderstood how Camunda is supposed to handle these situations?