The BPM OData Service is a built-in REST service exposing selected functionalities of the BPM Public API. The service implements the Open Data Protocol (OData) and thus provides a uniform way to easily access the exposed data and functionalities. With help of this service you can easily implement a custom UI with access to BPM related data and operations. This accelerates, for example, the implementation of a custom Task Execution UI with SAPUI5, since SAPUI5 can directly connect with the service to fetch data or perform actions. This is shown in the second post of this series. The goal of this blog post is to explain the technical basics of the BPM OData Service and to demonstrate how to explore this service.
URL Part / Service Name | BPM Tasks OData Service | BPM Task Data OData Service |
---|---|---|
Technical Service Name | tasks.svc | taskdata.svc |
Use Case | Get metadata of a task, claim a task | Get task input and output data, complete a task |
Required Path Segment(s) | - | Task instance ID value |
Supported OData Resource Paths | $metadata, TaskCollection, Claim | $metadata, InputData, OutputData |
Supported OData Query Options | $format | $expand, $format |
<complexType name="Customer">
<sequence>
<element name="firstName" type="string"></element>
<element name="lastName" type="string"></element>
<element name="address-street" type="string"></element>
<element name="address-city" type="string"></element>
<element name="address-zip" type="integer"></element>
<element name="address-country" type="string"></element>
<element name="currency" type="string" default="EUR"></element>
</sequence>
</complexType>
<complexType name="Credit">
<sequence>
<element name="creditLimit" type="double"></element>
</sequence>
</complexType>
Based on the technical basics described in the previous section, the following sections are now getting back to the steps needed to come from A to Z. This section starts with step A and describes how to access the metadata of a BPM task in order to inspect, for example, the priority of a task. The data referred here as metadata of a task corresponds to the TaskAbstract known from the BPM Public API.
In order to get the metadata of a task, the BPM Tasks OData Service is used along with the OData resource path TaskCollection. The Task instance ID is passed as URL parameter in parentheses and quotation marks. The OData $format query option is used to specify that the service response should be in JSON format.
The table below shows the URL used to access the metadata of a BPM task along with the service response:
HTTP Method | GET |
---|---|
URL | .../bpmodata/tasks.svc/TaskCollection('e898ab9c36f611e3a6bf0000006379d2')?$format=json |
Response Body (simplified) |
|
The response of the HTTP request above contains the requested data in a key-value pair format. OData supports the possibility to describe the underlying data model, the so-called Entity Data Model (EDM). This data model is exposed with a Service Metadata Document describing entities, their properties and relations among different entities. With help of this information you can for example find out, that the priority of a task is a property of type String and the property is optional (Nullable=true). This document can be requested with the $metadata query option.
The table below shows the URL used to get the metadata of the BPM Tasks OData Service and the corresponding response:
HTTP Method | GET |
---|---|
URL | .../bpmodata/tasks.svc/$metadata |
Response Body (simplified) |
|
The input data of a task contains the data used to initialize the task while the output data contains the result of the completed task.
Accessing the input data returns a data object called InputData which contains the data as specified with the input data mapping of the human activity within the process model. In the running example it is an entity called Customer containing the data set of a customer with the first name John and the last name Doe.
In order to get the Input Data of a Task, the BPM Task Data OData Service is used along with the OData resource path InputData. The Task instance ID is passed as URL path segment and as URL parameter. It is also possible not to pass the task instance ID as parameter, but this will change the format of the response. Instead of returning the Input Data as a single entity, an Atom feed is returned which contains the Input Data as single element.
The OData $expand query option is used to specify that referenced entities should be represented inline within the service response. The name of the entities to expand is passed with the option. In the example below the referenced entity Customer is getting expanded and therefore represented inline in the response. Omitting the expand option would result in a service response containing only the wrapper element InputData without any further data.
The table below shows the URL used to access the input data of a BPM task along with the service response:
HTTP Method | GET |
---|---|
URL | .../bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/InputData(' e898ab9c36f611e3a6bf0000006379d2')?$expand=Customer&$format=json |
Response Body |
|
Like the BPM Tasks OData Service, the BPM Task Data OData Service also supports requesting the Service Metadata Document, but specific for each particular task instance ID. This document describes the structure of the input data as well as the structure of the output data. The returned EDM is generated automatically from the XSD defining the data types used by the BPM task and thus provides the information about name, type and default value of the single properties.
In the example below, the task Verify Customer Data is used. The input and output data of this task have the same data type, i.e. Customer. This is also reflected in the resulting EDM. In case of a different XSD structure for input and output data, EDM structure would differ as well.
The table below shows the URL used to get the metadata of the BPM Task Data OData Service and the corresponding response:
HTTP Method | GET |
---|---|
URL | .../bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/$metadata |
Response Body (simplified) |
|
The service request to get the task output data is almost the same as the one to get the input data except of the OData entity set name that is OutputData in this case. Requesting the output data of an open task will return an empty data object, since the output data of a task is only set when completing the task.
The table below shows the URL used to access the output data of a BPM task along with the service response:
HTTP Method | GET |
---|---|
URL | .../bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/OutputData(' e898ab9c36f611e3a6bf0000006379d2')?$expand=Customer&$format=json |
Response Body |
|
In SAP NetWeaver BPM, you must claim a task before you will be able to complete it. This can be done with help of the BPM Tasks OData Service using the OData resource path Claim. The task instance ID of the respective task is passed with the query option InstanceID.
In contrast to the requests mentioned before (for example, getting the input data of a task), this activity is not about getting some data from the OData Service but about executing a particular action, i.e. claiming a task. Thus, an HTTP POST request is used to trigger the action instead of an HTTP GET request, which is usually used to request some data. A POST request includes some headers and a body containing some data. The headers are explained later along with a description of how you could actually execute a POST request.
The table below shows the URL used to claim a BPM task:
HTTP Method | POST | |
---|---|---|
URL | .../bpmodata/tasks.svc/Claim?InstanceID='e898ab9c36f611e3a6bf0000006379d2' | |
Request Headers | Authorization | Basic dXNlcm5hbWU6cGFzc3dvcmQ= |
X-CSRF-Token | 781057a9-b96a-468c-b393-981f98292335 | |
Request Body | <empty> | |
Response Body | OData entry representing the claimed BPM Task |
Once the task is claimed, you will be able to complete it. For that purpose, you send an HTTP POST request to the URL similar to the one that is used to get the task output data. The request body contains the output data that will be used to complete the task. In case of the running example, a modified version of the input data is used to complete the task. This is possible because the task uses the same data type for input and output data. If the data types for input and output data are different, the output data needs to be created based on the described structure in the EDM.
The table below shows the URL used to complete a BPM task along with the service response:
HTTP Method | POST | |
---|---|---|
URL | .../bpmodata/taskdata.svc/e898ab9c36f611e3a6bf0000006379d2/OutputData | |
Request Headers | Authorization | Basic dXNlcm5hbWU6cGFzc3dvcmQ= |
X-CSRF-Token | 781057a9-b96a-468c-b393-981f98292335 | |
Accept | application/json | |
Content-Type | application/json | |
Request Body |
| |
Response Body |
|
Attentive readers probably noticed that the currency property has not been specified in the POST request body, but it is set to EUR in the service response. In case the value for a required property is not provided in the POST request body (currency is a required element having defined a default value in the XSD definition), the service will use its default value to complete the task.
As it was mentioned before, HTTP POST requests are used to claim and complete a BPM task. For performing a POST request a regular web browser cannot be used. To perform a POST request you need to use a REST client. For this purpose, we will use Postman. It is a REST client distributed as an add-on for Google Chrome browser. In case you want to use your own REST client instead of Postman, please make sure that the client supports the reuse of the same HTTP session across different HTTP requests. Otherwise, you might face with problems during claiming or completing a BPM task.
The screenshot below shows how to send a POST request to complete a BPM task with Postman:
As some of you probably noticed there are some HTTP headers specified for the POST requests to claim and complete the task. Content-Type and Accept are standard HTTP headers used to specify media type for the request and response bodey respectively. Authorization header is used to specify user credentials for authentication. In the example, this header has a Base64-encoded value generated by Postman. To generate this value in Postman go to the Basic Auth tab of the Postman UI, enter user credentials and click the Refresh headers button.
A POST request can be considered as a write operation. It means that additional security considerations should be taken into account to secure BPM process data. The BPM OData services are implemented to prevent CSRF attacks in case write operation is performed. This is implemented with the HTTP header X-CSRF-Token, which is used to send CSRF tokens in both directions. As it was mentioned before, this header is checked only for write operations, i.e. only for POST requests. The CSRF token is generated by the service, which means that before you specify the header value for a POST request you need to get it from the service. For that purpose, you can send any valid GET request to the service adding X-CSRF-Token HTTP header with the value Fetch. After receiving the generated value from the service, you can use this value in the HTTP header of your POST request to complete a task. The generated value is valid only within the same HTTP session.
The figure below shows the URL used to request the generation of the value for the X-CSRF-Token header along with the response containing the generated value:
Providing access to a task’s input and output data requires knowledge of the used data types. In BPM these data types are defined with an XML Schema Definition (XSD). This XSD is translated by the BPM OData Service in an OData conform representation of the data structure, i.e. EDM. As of SAP NetWeaver 7.3 EHP1 SP09, this translation only supports a complex type acting as a wrapper, which contains some primitive types. See also the running example, which uses a complex type Customer with primitive types describing the name and the city of the customer.
In case your wrapper element does not only contain primitive types but also complex types, you can bypass this restriction by unwinding the embedded complex types to own simple properties with the name of the complex data type as prefix. This workaround is shown below:
Complex type unwound to simple properties:
<complexType name="Customer">
<sequence>
<element name="firstName" type="string"></element>
<element name="lastName" type="string"></element>
<element name="address-street" type="string"></element>
<element name="address-city" type="string"></element>
<element name="address-zip" type="integer"></element>
<element name="address-country" type="string"></element>
<element name="currency" type="string" default="EUR"></element>
</sequence>
</complexType>
Use of embedded complex type:
<complexType name="Customer">
<sequence>
<element name="firstName" type="string"></element>
<element name="lastName" type="string"></element>
<element name="address" type="Address"></element>
<element name="currency" type="string" default="EUR"></element>
</sequence>
</complexType>
<complexType name="Address">
<sequence>
<element name="street" type="string"></element>
<element name="city" type="string"></element>
<element name="zip" type="integer"></element>
<element name="country" type="string"></element>
</sequence>
</complexType>
More information about the restrictions of the BPM OData Service as of SAP NetWeaver 7.3 EHP1 SP09 you can find in the BPM OData Services documentation.
Sometimes bad things happen. In case something goes wrong during the service request processing, you will get a service response containing a log ID along with a corresponding HTTP status code, e.g. HTTP 500 (Internal Server Error) or HTTP 404 (Not Found). You can inspect the log entry identified with the given log ID by using the SAP NetWeaver Log Viewer. The technical information about the error including the exception stack trace is located in SAP NetWeaver Developer Traces.
This part has shown the whole round-trip for a BPM task; the metadata and the input data of a task can be retrieved, a task can be claimed for a given user, and the output data can be sent to complete a task. In the next part we will show how this round-trip of operations can be used to implement a Task Execution UI based on SAPUI5.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
24 | |
11 | |
11 | |
10 | |
7 | |
7 | |
6 | |
6 | |
5 | |
5 |