0
  1. Create Order triggers the Rest End point and starts the workflow (Its a TASK ). CreateOrderController

Problem is CreateOrderController is always returning Success.I want to return ResponseEntity.ok("Not Success "); as shown in 2nd image and stop the call of Save Order Database How to achieve it?

> @RestController
> public class CreateOrderController {
> 
>   @Autowired
>   private RuntimeService runtimeService;
> 
> 
> 
>   @PostMapping("/rest/create/order")
>   public ResponseEntity<?> createOrder(@RequestBody OrderInfo orderInfo) {
> Map<String, Object> inputData = new HashMap<String, Object>();
>       inputData.put("orderInfo", orderInfo);
>      ProcessInstance p = runtimeService.startProcessInstanceByKey("hello-world-process",inputData);
>      
>      
> 
>       return ResponseEntity.ok("Success");
> 
>   }

enter image description here enter image description here

enter image description here

Hello
  • 57
  • 5

1 Answers1

0

If you are executing the complete process in one transaction, then an exception along the way will create a rollback. However, you usually have a transaction boundary somewhere. You can query the status of the process instance after it has been started via the history endpoint.

The execute method returns void. Let the delegate write process data instead of returning a value. You can find a setVariable method on the delegateExecution you are getting in as a parameter.

You can get the data values in the REST response as shown in this example: https://docs.camunda.org/manual/7.18/reference/rest/process-definition/post-start-process-instance/#starting-a-process-instance-with-variables-in-return

Request:

{
 "variables":{
   "aVariable" : {
     "value" : "aStringValue",
     "type": "String"},
   "anotherVariable" : {
     "value" : true,
     "type": "Boolean",
     "valueInfo" : {
        "transient" : true
      }
    }
 },
 "businessKey" : "myBusinessKey",
 "withVariablesInReturn": true
}

Response

{
  "links": [
    {
      "method": "GET",
      "href": "http://localhost:8080/rest-test/process-instance/aProcInstId",
      "rel": "self"
    }
  ],
  "id": "aProcInstId",
  "definitionId": "aProcessDefinitionId",
  "businessKey": "myBusinessKey",
  "ended": false,
  "suspended": false,
  "tenantId": null,
  "variables": {
    "anotherVariable": {
        "type": "Boolean",
        "value": true,
        "valueInfo": {
          "transient" : true
        }
    },
    "aVariable": {
        "type": "String",
        "value": "aStringValue",
        "valueInfo": { }
    }
  }
}

Alternatively, error handling options in the delegate code / process include:

a) Simply throw an exception in your execute() method, for instance a new RuntimeException() and observe in Cockpit how Camunda creates a technical incident for the process (https://docs.camunda.org/manual/7.18/webapps/cockpit/bpmn/failed-jobs/).

b) You can also use custom exceptions and error codes, e.g. as shown here:

// Defining a custom exception.
public class MyException extends ProcessEngineException {

  public MyException(String message, int code) {
    super(message, code);
  }
}

// Delegation code that throws MyException with a custom error code.
public class MyJavaDelegate implements JavaDelegate {

  @Override
  public void execute(DelegateExecution execution) {
    String myErrorMessage = "My error message.";
    int myErrorCode = 22_222;
    throw new MyException(myErrorMessage, myErrorCode);
  }

}

Src: https://docs.camunda.org/manual/7.18/user-guide/process-engine/delegation-code/#exception-codes

c) If you don't want to create e technical incident but prefer to throw a 'business' error which you can catch in the process model, so the process can take a different (error) path:

public class BookOutGoodsDelegate implements JavaDelegate {

  public void execute(DelegateExecution execution) throws Exception {
    try {
        ...
    } catch (NotOnStockException ex) {
        throw new BpmnError("Business issue");
    }
  }

}

src: https://docs.camunda.org/manual/7.18/user-guide/process-engine/delegation-code/#throw-bpmn-errors-from-delegation-code

rob2universe
  • 7,059
  • 39
  • 54
  • Thanks for your response. I am returning ` return ResponseEntity.ok("Not Success")` and not throwing an exception.So whatever value i am returning from Delegate code the Rest Controller should return that as a Response to the client and workflow should end .I have provided the image. – Hello Nov 23 '22 at 06:48
  • Update the answer fro this sceanrio – rob2universe Nov 23 '22 at 07:36
  • If i understand correctly, you are suggesting to `delegate.setVariable("value to be returned "); and stop the workflow in that Delegate` and get this value in RestController by calling the rest api.And is there any Java method to get the value in Rest Controller . – Hello Nov 23 '22 at 08:55
  • The rest controller starts the process and the same thread executes the process (if there is no transaction boundary). As part of the process the delegate sets the process data. As the thread will only return when the process is completed, the start process call will return only when the process is completed and the response will include the data the delegate set – rob2universe Nov 23 '22 at 08:58
  • yup got it so my understanding is correct. Is there any Java hook(method) to get the value set by delegates classes in the Rest controller after the process is complete.I have attached the last image in the original question – Hello Nov 23 '22 at 09:05
  • If it is a sync execution, then data is returned in the response. If the start call has already returned then you can send another request to query process instance information and data fro instance https://docs.camunda.org/manual/7.18/reference/rest/history/variable-instance/ or https://docs.camunda.org/manual/7.18/reference/rest/history/process-instance/ – rob2universe Nov 23 '22 at 09:23
  • Yes but u see my code controller always return `return ResponseEntity.ok("Success");` but in my delegegate i set variable as `ResponseEntity.ok("Not Success")` – Hello Nov 23 '22 at 09:28
  • Please update the code of your JavaDelegate in the question. It should not return anything. It should just update the data via execution.setVariable() – rob2universe Nov 23 '22 at 10:00
  • Let me upload the whole code on github today.Will post the link to github – Hello Nov 23 '22 at 11:07
  • i have uploaded the code in github.Its simeple.Please read the README. https://github.com/rahul-raj-1/camunda-rnd-repo – Hello Nov 23 '22 at 15:11
  • Here a working example:https://github.com/rahul-raj-1/camunda-rnd-repo/pull/1 – rob2universe Nov 24 '22 at 05:01
  • Thanks.I had also got the same solution just 1 hour back.Thanks to this stackoverflow post https://stackoverflow.com/questions/38328208/how-to-retrieve-process-variable-in-camunda-bpm/38346208#38346208 – Hello Nov 24 '22 at 05:19
  • isnt ur code in `Step1Delegate ` class wrong.If `orderId < 0)` then it throws BPMN error and `execution.setVariable` is never executed ? – Hello Nov 24 '22 at 07:35
  • 1
    I was not setting the data in this scenario but showing you the BppmnError option instead. The controller creates a dummy response when the value is null. Of course you could also always set the data, but then you wouldn't throw the BPMNErrror. Instead you would work with a gateway following the task completion to evaluate the data and the path you want to take. – rob2universe Nov 25 '22 at 00:29