Start process from external Task form

Hello
I stuck with a problem, I’m trying to integrate task external form written on React and embedded at StartEvent point and everything is ok, but only one problem I can’t understand, when I open my custom form how can I interact with a process, get the process instances and the main problem is complete this point and return to Camunda?

From a JavaScript form your best bet is to use the REST API - which is documented here. Depending on what exactly you’re trying to do one or more rest calls may be required.

Thank you for advice @Niall

Now I start process through REST api, but I can fetch only few parameters from started process and I also need to define which user was authorized at that moment, maybe you could recommend How can I do it? some sample or even concept way how to do it, because I’m trying and it gave no result.

Here is sample (maybe anybody need it):

 <div class="container-fluid">

    <h1>Test content</h1>

    <div class="form-group">
        Start a new process instance:
        <input type="text" id="testParameter"></input>
        <button onclick="startProcessInstance()" class="btn btn-default">Start</button>
    </div>

</div>
<script>
    var REST_BASE_URL = "http://localhost:8080/engine-rest/engine/default";

    function startProcessInstance() {
        var startRequest = {"variables":
                {
                    "Parameters" : {"value" : $("#testParameter").val(), "type": "String"},
                }
        }
        $.ajax(REST_BASE_URL + '/process-definition/key/reactForm/start', {
            data: JSON.stringify(startRequest),
            contentType : 'application/json',
            type : 'POST',
            success: function (result) {
                let object = JSON.stringify(result);
                console.log(object);
                console.log(result.id);
            }
        });
    }
</script>

Hello Team (@Niall and @jonathan.lukas )

Such a great post, thank you(@Mykhailo ) in advance for your proper reply.

We have found the post according to our requirement.
As you have described, we developed a module via Rest API for starting any kind of process from the External Task Service (in JAVA).It could be call with different parameters (id , processKey , tenentId). So you could call it from your JS source code easily without any extra development.

I have developed SetVariable method for external task some days ago and we could contribute on this module too.

I have developed below source code on External Task project and attached each modification separately.

EngineClient.java

 // public static final String PROCESS_DEFINITION =  "/process-definition";
 // public static final String TENANT_ID =  "/tenant-id";
 // public static final String START =  "/start";
 // public static final String KEY =  "/key";


  public void startProcess(String id, String processKey, String tenantId, String businessKey, VariableMap variables, String caseInstanceId) throws EngineClientException {
    StartProcessRequestDto payload = new StartProcessRequestDto(variables, businessKey, caseInstanceId);
    String resourcePath = id != null ? MessageFormat.format("{0}/{1}{2}", PROCESS_DEFINITION, id, START) :
            MessageFormat.format("{0}{1}/{2}{3}{4}", PROCESS_DEFINITION, KEY, processKey, tenantId != null ?
            MessageFormat.format("{0}/{1}", TENANT_ID, tenantId) : "", START);
    String resourceUrl = baseUrl + resourcePath;
    engineInteraction.postRequest(resourceUrl, payload, Void.class);
  }

ExternalTaskServiceImpl.java


  public void startProcess(ExternalTask externalTask, String id, String processKey, String tenantId, VariableMap variables, String caseInstanceId) {
    try {
      engineClient.startProcess(id, processKey, tenantId, externalTask.getBusinessKey(), variables, caseInstanceId);
    } catch (EngineClientException e) {
      throw handleException(e, "extending lock", true);
    }
  }

ExternalTaskService.java (interface)

According to below code, we have prepared startProcess definition and write in related interface.

  /**
   * Start Process
   *
   * @param id indicates the identifier for process instance.
   * @param processKey indicates the master keys for process instance.
   * @param tenantId indicates the identifier for tenant part.
   * @param variables provides related variables to the process.
   * @param caseInstanceId indicates the identifier for instance of case.
   *
   * @throws NotFoundException if the task has been canceled and therefore does not exist anymore
   * @throws NotAcquiredException if the task's most recent lock could not be acquired
   * @throws ConnectionLostException if the connection could not be established
   * @throws ValueMapperException
   * <ul>
   *   <li> if an object cannot be serialized
   *   <li> if no 'objectTypeName' is provided for non-null value
   *   <li> if value is of type abstract
   *   <li> if no suitable serializer could be found
   * </ul>
   */

  void startProcess(ExternalTask externalTask, String id, String processKey, String tenantId, VariableMap variables, String caseInstanceId);

StartProcessRequestDto.java

Then we have main class that will handle requestDto part as below class

import org.camunda.bpm.engine.variable.VariableMap;

public class StartProcessRequestDto {
    // no contain workerId

    protected VariableMap variables;
    protected String businessKey;
    protected String caseInstanceId;

    public StartProcessRequestDto(VariableMap variables, String businessKey, String caseInstanceId) {
        this.variables = variables;
        this.businessKey = businessKey;
        this.caseInstanceId = caseInstanceId;
    }

    public VariableMap getVariables() {
        return variables;
    }

    public String getBusinessKey() {
        return businessKey;
    }

    public String getCaseInstanceId() {
        return caseInstanceId;
    }
}

In the end, I prepared a sample test and catch a successful response from the Engine.


   public static void main(String[] args) {

        // Personal Test
        ExternalTaskClient client = ExternalTaskClient.create()
                .baseUrl("http://10.1.2.51:8080/engine-rest")
                .asyncResponseTimeout(10000) // long polling timeout
                .build();

        client.subscribe("charge-card")
                .lockDuration(1000)
                .handler((externalTask, externalTaskService) -> {

                   VariableMap variables = new VariableMapImpl();
                   variables.putValueTyped("aVariable", Variables.stringValue("aNewValue"));
                   variables.putValueTyped("anotherVariable", Variables.booleanValue(true));

                   externalTaskService.startProcess(externalTask, null, "aKey", "aTenantId", variables, "aCaseInstanceId");

                   externalTaskService.complete(externalTask);
                })
                .open();
    }

We could start the proper process with related params from the External Task successfully.

It’s our pleasure if we could contribute to this module too.

Let me know your feedback

Best Regards,

Taha Arian

1 Like

Hello again Team (@Niall and @jonathan.lukas )

According to the comment we could contribute in developing this module if you prefer.

Let me know your feedbacks

Best Regards,

Taha Arian