Bonita is an open and extensible application platform that takes an API first approach to the design and development of business processes. Bonita leverages REST APIs to facilitate interactions with the core of its business process management capability. Everything from creating users, deploying processes, acquiring and actioning tasks is accomplished through the provided REST APIs. This is a great asset of the solution however you may hit a roadblock when you need to do something outside of the default APIs. This is where REST API extensions come into play. They are deployed into the Bonita runtime platform and can be invoked in exactly the same way as the default REST APIs provided by the system.
The subscription editions of Bonita provides integrated development capabilities into the Studio designer, however this blog post will explain how to setup a framework based on industry standard java and maven tooling which can be used in both the community and subscription editions.
The following sections walk you through:
- Setting up the project structure
- Creating a simple REST API extension
- Deploying the REST API extension to an existing (community or subscription) Bonita server
- Invoking the REST API extension
Set Up
Rather than walking you through all the nitty-gritty details of setting up a maven project from scratch, you can head over to https://github.com/kevin-henshall-ip/bonita on github and simply download or clone the repository. This section assumes that you have done this and will provide only a summary of the key files.
restApiExtensions/
src/main/resources/page.properties – The main configuration file for a REST API extension. It contains the following details for each REST API extension endpoint:
- HTTP method
- Entry point groovy class (which in this case, points to com.company.rest.api.RestApiEntryPoiint.groovy)
- Security (which for now we will configure to allow access to all users)
src/main/java/com/company/rest/api/
- RestApiEntryPoint.groovy – The groovy entry point for the REST API. Note that bonita requires that the entry point be a groovy class. However, since we will be using java for the core of the REST API, a simple groovy class which extends a java class is used
- TemplateRestApi.java – The core java entry point of the REST API which extends BaseRestApiExtension ensuring that the appropriate doHandle method is implemented
- TemplateRestApiResponse.java – Defines the response structure
Creating a simple REST API extension
Rather than create a new REST API extension from scratch, we will copy the existing templateRestApi directory and name it sampleRestApi. Once copied, perform the following:
restApiExtensions/pom.xml – Add the sampleRestApi as a module:
<modules> <module>commonRestApiUtilities</module> <module>templateRestApi</module> <module>sampleRestApi</module> </modules>
sampleRestApi: pom.xml – Update the artifactId, name and description tags:
<artifactId>sampleRestApi</artifactId> <name>sampleRestApi</name> <description>Sample REST API</description>
src/main/resources/page.properties – Update references to templateRestApi with sampleRestApi:
... name=custompage_sampleRestApi displayName=sampleRestApi description=Sample REST API contentType=apiExtension apiExtensions=sampleRestApi sampleRestApi.method=GET sampleRestApi.pathTemplate=sampleRestApi sampleRestApi.classFileName=com/company/rest/api/RestApiEntryPoint.groovy sampleRestApi.permissions=case_visualization ...
src/main/java/com/company/rest/api
- Rename TemplateRestApi.java to SampleRestApi.java and update references in the source code appropriately
- Rename TemplateRestApiResponse.java to SampleRestApiResponse.java
- RestApiEntryPoint.java – Update to extend SampleRestApi
src/test/java/com/company/rest/api
- Rename TemplateRestApiTest.java to SampleRestApiTest and update references in the source code appropriately
Writing the custom code
So far, we’ve explained how to create the structure of a bonita REST API and in this section we will provide an example of some code which interacts with the bonita engine. In particular, we are going to modify our sample REST API to return the details of the user invoking the API and also a list of tasks which are assigned to them.
So to start, let’s update the SampleRestApiResponse class to define the desired response fields:
package com.company.rest.api; import org.bonitasoft.engine.bpm.flownode.HumanTaskInstance; import org.bonitasoft.engine.identity.impl.UserImpl; import java.util.List; public class SampleRestApiResponse { private UserImpl currentUser; private List<HumanTaskInstance> humanTasksAssignedToCurrentUser; // getters and setters omitted for brevity }
The UserImpl and HumanTaskInstance classes represent the user and task objects respectively.
In order to retrieve the current user details, we will utilise the following:
long currentUserId = restApiContext.getApiSession().getUserId(); UserImpl currentUser = new UserImpl(getIdentityApi().getUser(currentUserId));
In the above, the getIdentityApi method provides access to bonita’s identity API which provides numerous methods to interact with bonita’s user, group, role and membership objects. In this case, we are retrieving the current user ID from the API session and then creating a new UserImpl object representing the user.
To retrieve the list of tasks assigned to the user, we will use bonita’s process API and search for tasks which are assigned to the current user:
SearchOptions searchOptions = new SearchOptionsBuilder(0, Integer.MAX_VALUE).filter(HumanTaskInstanceSearchDescriptor.ASSIGNEE_ID, currentUserId).done(); SearchResult<HumanTaskInstance> humanTasksAssignedToUserSearchResult = getProcessApi().searchHumanTaskInstances(searchOptions); List<HumanTaskInstance> humanTasksAssignedToCurrentUser = humanTasksAssignedToUserSearchResult.getResult();
If you wish to check out the completed code for the sample REST API check out the sampleRestApi branch on github: https://github.com/kevin-henshall-ip/bonita/tree/sampleRestApi/restApiExtensions
Building REST API extensions
To build the sample REST API, navigate to the restApiExtensions directory and run the following:
mvn clean package --projects sampleRestApi --also-make
This will produce a zip file named sampleRestApi-1.0-SNAPSHOT.jar within the sampleRestApi/target directory which we can deploy to a bonita server as outlined below.
Deploying REST API extensions
In order to deploy the REST API extension, open a browser and login to the bonita portal (e.g. http://localhost:8080/bonita) as a user who is an Administrator. Navigate to the ‘Resources’ tab and then click ‘Add’. Select the built REST API extension zip file and click ‘Next’ and then ‘Confirm’. The REST API extension should now be deployed and you should be able to invoke it by simply navigating to the appropriate endpoint (e.g. http://localhost:8080/bonita/API/extension/sampleRestApi) which will return a response similar to the following:
{ "currentUser": { "id": 4, "firstName": "Walter", "lastName": "Bates", "password": "", "userName": "walter.bates", "iconId": null, "title": "Mr", "jobTitle": "Human resources benefits", "creationDate": "2018-04-24T14:09:53.666+1000", "createdBy": -1, "lastUpdate": "2018-04-24T14:09:53.666+1000", "lastConnection": "2018-04-27T07:30:10.129+1000", "managerUserName": null, "managerUserId": 3, "enabled": true }, "humanTasksAssignedToCurrentUser": [ { "actorId": 1, "assigneeId": 4, "priority": "NORMAL", "expectedEndDate": null, "claimedDate": "2018-04-27T07:30:42.250+1000", "parentContainerId": 1, "state": "ready", "stateCategory": "NORMAL", "rootContainerId": 1, "processDefinitionId": 7629126156073007208, "parentProcessInstanceId": 1, "displayDescription": null, "displayName": "Review task", "description": null, "executedBy": 0, "executedBySubstitute": 0, "flownodeDefinitionId": 5946836920024332147, "reachedStateDate": "2018-04-27T07:30:24.792+1000", "lastUpdateDate": "2018-04-27T07:30:24.792+1000", "name": "Review task", "id": 2 } ] }
Intelligent Pathways is a Bonita Premier Partner with several years of experience implementing Bonita processes, connectors and REST API extensions.