This blog post, as part 7 of BPM OData blog series, refers to the OData Service in SAP BPM available with SAP NetWeaver 7.3 EHP 1 SP 09 and higher. The features described in this blog post are available with SAP NetWeaver 7.3 EHP 1 SP 16 and higher (and in 7.4 SP 11 and higher, respectively). Before reading this blog post, we recommend reading the previous parts of BPM OData blog series.

Overview

The purpose of this blog post is to introduce the new features, which are available with the BPM OData services starting from SAP NetWeaver 7.3 EHP 1 SP 16. These new features include:

  • The new BPM Messages OData service
  • Support of additional URIs in the BPM Process Start OData service

In scope of this blog post, only technical details of the aforementioned features are described along with some examples.

BPM Messages OData Service

Starting from SAP NetWeaver 7.3 EHP 1 SP 16, BPM OData service provides the functionality to send messages to the intermediate message events. As all the already existing BPM OData services, the new BPM Messages OData service is available under ‘bpmodata’ root URL and has the name ‘messages.svc’. The set of operations provided by the service includes getting information about the structure of the message for an intermediate message event, and sending the message to an intermediate message event. You can find more information about the intermediate message events in the official documentation.

At design time in Process Composer, the structure of the message is defined in the WSDL interface, which is assigned to a message event trigger. That message event trigger is then consumed by one or many  intermediate message events in BPM process models.

When invoking the BPM Messages OData service, it is always required to specify which event trigger shall be used in that particular call. Every message event trigger in SAP BPM can be uniquely identified by the following three properties:

  • Name of the vendor of the development component where the event trigger is located
  • Name of the development component where the event trigger is located
  • Name of the event trigger

As a result, each URI for the BPM Messages OData service should contain these three identifiers. As usual, in the BPM OData services, these identifiers are provided in the URI preceding path segments. Therefore, all the service URIs must follow the following pattern:

http://<host>:<port>/bpmodata/messages.svc/<vendor>/<dc-name>/<trigger-name>/<OData_resource_path_and_query_options>

Running Example

Before starting with the examples of the URIs for the BPM Messages OData service, it is worth modifying the BPM process, which has been used in the previous blog posts, by adding an intermediate message event to the process model. The modified version of the BPM process is shown below:

/wp-content/uploads/2015/06/process_model_656680.png

An intermediate message event with the name ‘Customer Record Created’ has been added to the process model right after the ‘Create Customer Record’ activity. The purpose of this intermediate message event is to be called by the backend system, which is responsible for the creation of the customer record, once the record is created. The created customer record is passed to the intermediate message event as a message. As a result, calling the intermediate message event is considered to be the confirmation of the successful creation of the customer record, which also means that the entire process can be completed.

The message received by the intermediate message event represents the created customer record. Therefore, the same XSD definition as in the previous blog posts is used:


<complexType name="Customer">
    <sequence>
        <element name="firstName" type="string"></element>
        <element name="lastName" type="string"></element>
        <element name="address" type="tns:Address"></element>
        <element name="currency" type="string" default="EUR"></element>
        <element name="phone-numbers" type="string" maxOccurs="unbounded"
            minOccurs="0"></element>
        <element name="vcards" type="tns:Vcard" maxOccurs="unbounded"
            minOccurs="0"></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>
<complexType name="Vcard">
    <sequence>
        <element name="attr1" type="string"></element>
        <element name="attr2" type="string"></element>
        <element name="attr3" type="string"></element>
    </sequence>
</complexType>













Having the modified BPM process, it is time to start using it via the BPM Messages OData service.

Getting Structure of the Message for the Intermediate Message Event

As it was mentioned previously, one of the operations provided by the BPM Messages OData service is to inform about the specifically modeled structure of the message for an intermediate message event. The structure can be retrieved by either sending a $metadata request to the service or by getting data for the corresponding entities.

The table below shows the URL used to get the service metadata along with the service response:

HTTP Method GET
URL

…/bpmodata/messages.svc/test.sap.com/tc~bpem~customer~process/CustomerRecordCreated/$metadata

Response Body

(simplified)


<EntityType Name="EventTrigger">
    <Key>
        <PropertyRef Name="vendor"></PropertyRef>
        <PropertyRef Name="dcName"></PropertyRef>
        <PropertyRef Name="eventTriggerName"></PropertyRef>
    </Key>
    <Property Name="vendor" Type="Edm.String" Nullable="false"></Property>
    <Property Name="dcName" Type="Edm.String" Nullable="false"></Property>
    <Property Name="eventTriggerName" Type="Edm.String" Nullable="false"></Property>
    <NavigationProperty Name="message"
        Relationship="BPMMessages.EventTrigger_message" FromRole="From_EventTrigger"
        ToRole="To_Message"></NavigationProperty>
</EntityType>
<EntityType Name="Message">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <NavigationProperty Name="Customer"
        Relationship="BPMMessages.Message_Customer" FromRole="From_Message"
        ToRole="To_Customer"></NavigationProperty>
</EntityType>
<EntityType Name="Customer">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="firstName" Type="Edm.String" Nullable="true"></Property>
    <Property Name="lastName" Type="Edm.String" Nullable="true"></Property>
    <Property Name="currency" Type="Edm.String" Nullable="true"
        DefaultValue="EUR"></Property>
    <NavigationProperty Name="address"
        Relationship="BPMMessages.Customer_address"
FromRole="From_Customer"
        ToRole="To_Address"></NavigationProperty>
    <NavigationProperty Name="phone-numbers"
        Relationship="BPMMessages.Customer_phone-numbers"
FromRole="From_Customer"
        ToRole="To_phone-numbers"></NavigationProperty>
    <NavigationProperty Name="vcards"
        Relationship="BPMMessages.Customer_vcards"
FromRole="From_Customer"
        ToRole="To_Vcard"></NavigationProperty>
</EntityType>
<EntityType Name="Address">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="street" Type="Edm.String" Nullable="true"></Property>
    <Property Name="city" Type="Edm.String" Nullable="true"></Property>
    <Property Name="zip" Type="Edm.Decimal" Nullable="true"></Property>
    <Property Name="country" Type="Edm.String" Nullable="true"></Property>
</EntityType>
<EntityType Name="phone-numbers">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="phone-numbers" Type="Edm.String" Nullable="true"></Property>
</EntityType>
<EntityType Name="Vcard">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="attr1" Type="Edm.String" Nullable="true"></Property>
    <Property Name="attr2" Type="Edm.String" Nullable="true"></Property>
    <Property Name="attr3" Type="Edm.String" Nullable="true"></Property>
</EntityType>













The service metadata has a number of standard entity types, such as EventTrigger and Message, as well as the entity types, which represent the message structure, i.e. Customer, Address, phone-numbers and Vcard. The purpose of the EventTrigger entity type is to store information about the message event trigger to which the message should be sent. The Message entity type is used as a wrapper for the entity types, which represent the message data. You can find more information about the entities in the BPM Messages OData service in the official documentation.

Based on the service metadata, the following request can be sent to get JSON entity for the message:

HTTP Method GET
URL

…/bpmodata/messages.svc/test.sap.com/tc~bpem~customer~process/CustomerRecordCreated/EventTrigger?$expand=message/Customer/address,message/Customer/phone-numbers,message/Customer/vcards&$format=json

Response Body

(simplified)


{
    "d": {
        "results": [
            {
                "vendor": "test.sap.com",
                "dcName": "tc~bpem~customer~process",
                "eventTriggerName": "CustomerRecordCreated",
                "message": {
                    "Customer": {
                        "firstName": null,
                        "lastName": null,
                        "currency": null,
                        "address": null,
                        "phone-numbers": {
                            "results": []
                        },
                        "vcards": {
                            "results": []
                        }
                    }
                }
            }
        ]
    }
}












As expected, the message entity is empty because the intermediate message event does not contain any default data.

Sending a Message to an Intermediate Message Event

Once we got the information about the structure of the message for the intermediate message event, it is time to provide some data for the message and send it. As usual, when some data has to be sent to an OData service, it should be provided in a POST request body for the specific entity set. In case of the BPM Messages OData service, in order to send a message to an intermediate message event, a POST request should be sent to one of the following entity sets: EventTrigger, Message or to the entity set which corresponds to the message data, i.e. ‘Customer’ in our case. A POST request body should contain a JSON entity for the corresponding entity set.

The table below shows the URL used to send a message to the intermediate message event along with the service response:

HTTP Method POST
URL …/bpmodata/messages.svc/test.sap.com/tc~bpem~customer~process/CustomerRecordCreated/EventTrigger
Request Headers Authorization Basic dXNlcm5hbWU6cGFzc3dvcmQ=
X-CSRF-Token 781057a9-b96a-468c-b393-981f98292335
Content-Type application/json
Accept application/json
Request Body

{
    "message" : {
        "Customer": {
            "firstName": "John",
            "lastName": "Doe",
            "currency": "USD",
            "address": {
                "street": "Main str.",
                "city": "Springfield",
                "zip": "12345",
                "country": "USA"
            },
            "phone-numbers": {
                "results": [
                            {
                                "phone-numbers": "111-111-111"
                            },
                            {
                                "phone-numbers": "222-222-222"
                            },
                            {
                                "phone-numbers": "333-333-333"
                            }
                ]
            },
            "vcards": {
                "results": [
                            {
                                "attr1": "John Doe",
                                "attr2": "john.doe_at_provider.com",
                                "attr3": "john.doe"
                            },
                            {
                                "attr1": "J.D.",
                                "attr2": "jd_at_provider.com",
                                "attr3": "jd"
                            }
                ]
            }
        }
    }
}












Response Body

(simplified)


{
    "d": {
        "vendor": "test.sap.com",
        "dcName": "tc~bpem~customer~process",
        "eventTriggerName": "CustomerRecordCreated",
        "message": {
            "Customer": {
                "firstName": "John",
                "lastName": "Doe",
                "currency": "USD",
                "address": {
                    "street": "Main str.",
                    "city": "Springfield",
                    "zip": "12345",
                    "country": "USA"
                },
                "phone-numbers": {
                    "results": [
                        {
                            "phone-numbers": "111-111-111"
                        },
                        {
                            "phone-numbers": "222-222-222"
                        },
                        {
                            "phone-numbers": "333-333-333"
                        }
                    ]
                },
                "vcards": {
                    "results": [
                        {
                            "attr1": "John Doe",
                            "attr2": "john.doe_at_provider.com",
                            "attr3": "john.doe"
                        },
                        {
                            "attr1": "J.D.",
                            "attr2": "jd_at_provider.com",
                            "attr3": "jd"
                        }
                    ]
                }
            }
        }
    }
}












The response body provides an entity for the message, which has been sent to the event trigger. And of course, BPM intermediate message events (and in general BPM start events as well) consuming the given message event trigger are receiving the message event and consume its data through the defined output mapping.

That’s all the main details about the BPM Messages OData service. You can find more information about the service itself, as well as about the supported URIs in the official documentation.

Because the same approaches and concepts are used in the BPM Messages OData service as in the existing BPM OData services, the service consumption via SAPUI5 should not be a problem for the users who did so previously. For those, who are new to the BPM OData services, the main details about the consumption of the services from SAPUI5 can be found at BPM OData: Implementing a Basic Custom Task Execution UI and BPM OData: Implementing an advanced custom task execution UI blog posts.

New URIs in the BPM Process Start OData Service

The BPM Process Start OData service has already been described in BPM OData: Implementing a Process Start UI blog post. In this section, only the new URIs, which are additionally supported starting with SAP NetWeaver 7.3 EHP 1 SP 16, are described.

Before starting with the examples of the new URIs, let us look again at the metadata of the BPM Process Start OData service from the previous blog post:


<EntityType Name="StartData">
    <Key>
        <PropertyRef Name="vendor"></PropertyRef>
        <PropertyRef Name="dcName"></PropertyRef>
        <PropertyRef Name="processTechnicalName"></PropertyRef>
    </Key>
    <Property Name="vendor" Type="Edm.String" Nullable="false"></Property>
    <Property Name="dcName" Type="Edm.String" Nullable="false"></Property>
    <Property Name="processTechnicalName" Type="Edm.String"
        Nullable="false"></Property>
    <Property Name="processInstanceId" Type="Edm.String" Nullable="true"></Property>
    <NavigationProperty Name="ProcessStartEvent"
        Relationship="BPMProcessStart.StartData_ProcessStartEvent" FromRole="From_StartData"
        ToRole="To_ProcessStartEvent"></NavigationProperty>
</EntityType>
<EntityType Name="ProcessStartEvent">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <NavigationProperty Name="Customer"
        Relationship="BPMProcessStart.ProcessStartEvent_Customer" FromRole="From_ProcessStartEvent"
        ToRole="To_Customer"></NavigationProperty>
</EntityType>
<EntityType Name="Customer">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="firstName" Type="Edm.String" Nullable="true"></Property>
    <Property Name="lastName" Type="Edm.String" Nullable="true"></Property>
    <Property Name="currency" Type="Edm.String" Nullable="true"
        DefaultValue="EUR"></Property>
    <NavigationProperty Name="address"
        Relationship="BPMProcessStart.Customer_address" FromRole="From_Customer"
        ToRole="To_Address"></NavigationProperty>
    <NavigationProperty Name="phone-numbers"
        Relationship="BPMProcessStart.Customer_phone-numbers" FromRole="From_Customer"
        ToRole="To_phone-numbers"></NavigationProperty>
    <NavigationProperty Name="vcards"
        Relationship="BPMProcessStart.Customer_vcards" FromRole="From_Customer"
        ToRole="To_Vcard"></NavigationProperty>
</EntityType>
<EntityType Name="Address">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="street" Type="Edm.String" Nullable="true"></Property>
    <Property Name="city" Type="Edm.String" Nullable="true"></Property>
    <Property Name="zip" Type="Edm.Decimal" Nullable="true"></Property>
    <Property Name="country" Type="Edm.String" Nullable="true"></Property>
</EntityType>
<EntityType Name="phone-numbers">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="phone-numbers" Type="Edm.String" Nullable="true"></Property>
</EntityType>
<EntityType Name="Vcard">
    <Key>
        <PropertyRef Name="EDM_Key"></PropertyRef>
    </Key>
    <Property Name="EDM_Key" Type="Edm.String" Nullable="false"></Property>
    <Property Name="attr1" Type="Edm.String" Nullable="true"></Property>
    <Property Name="attr2" Type="Edm.String" Nullable="true"></Property>
    <Property Name="attr3" Type="Edm.String" Nullable="true"></Property>
</EntityType>











Initially, all the URIs supported by the BPM Process Start OData service were based on the StartData entity set. Starting from SAP NetWeaver 7.3 EHP 1 SP 16, the corresponding requests can also be sent to the ProcessStartEvent entity set as well as to the main entity set which represents the process start data. In our particular case, the following requests can be sent to the service to get information about the structure of the process start data:

  • GET …/bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/ProcessStartEvent
  • GET …/bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/Customer

In order to start the process, the following requests are also supported now:

  • POST …/bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/ProcessStartEvent
  • POST …/bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/Customer

The POST request bodies for the aforementioned requests should contain entities for ProcessStartEvent and Customer entity types, respectively.

Support of the additional URIs makes the service consumption simpler, due to the following reasons:

  • Service URLs to get process start data will be shorter because of the shorter $expand option value: GET …bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/StartData?$expand=ProcessStartEvent/Customer/address,ProcessStartEvent/Customer/phone-numbers,ProcessStartEvent/Customer/vcards vs. GET …bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/Customer?$expand=address,phone-numbers,vcards
  • Content of the POST request body becomes smaller because the entity for the process start data (e.g. Customer) can be specified as it is, i.e. without specifying entities for the parent StartData and ProcessStartEvent entity types
  • The service consumption becomes similar to the BPM Task Data OData service, where POST request body contains only the entities for the task data itself.

Of course, it is better to see something once than hear about it a hundred times. So, let us go directly into the examples.

The table below shows the usage of the first option of the new URI (entity set ProcessStartEvent) in order to get information about the structure of the process start data along with the service response:

HTTP Method GET
URL

…/bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/ProcessStartEvent?$expand=Customer/address,Customer/phone-numbers,Customer/vcards&$format=json

Response Body

(simplified)


{
    "d": {
        "results": [
            {
                "Customer": {
                    "firstName": null,
                    "lastName": null,
                    "currency": null,
                    "address": null,
                    "phone-numbers": {
                        "results": []
                    },
                    "vcards": {
                        "results": []
                    }
                }
            }
        ]
    }
}










Once we have the structure for the process start data, the next step is to start the process. The table below shows the usage of the new URI in order to start the process along with the service response:

HTTP Method POST
URL …/bpmodata/startprocess.svc/test.sap.com/tc~bpem~customer~process/CreateCustomerProcess/ProcessStartEvent
Request Headers Authorization Basic dXNlcm5hbWU6cGFzc3dvcmQ=
X-CSRF-Token 781057a9-b96a-468c-b393-981f98292335
Content-Type application/json
Accept application/json
Request Body

{
    "Customer": {
        "firstName": "John",
        "lastName": "Doe",
        "currency": "USD",
        "address": {
            "street": "Main str.",
            "city": "Springfield",
            "zip": "12345",
            "country": "USA"
        },
        "phone-numbers": {
            "results": [
                        {
                            "phone-numbers": "111-111-111"
                        },
                        {
                            "phone-numbers": "222-222-222"
                        },
                        {
                            "phone-numbers": "333-333-333"
                        }
            ]
        },
        "vcards": {
            "results": [
                        {
                            "attr1": "John Doe",
                            "attr2": "john.doe_at_provider.com",
                            "attr3": "john.doe"
                        },
                        {
                            "attr1": "J.D.",
                            "attr2": "jd_at_provider.com",
                            "attr3": "jd"
                        }
            ]
        }
    }
}










Response Body

(simplified)


{
    "d": {
        "Customer": {
            "firstName": "John",
            "lastName": "Doe",
            "currency": "USD",
            "address": {
                "street": "Main str.",
                "city": "Springfield",
                "zip": "12345",
                "country": "USA"
            },
            "phone-numbers": {
                "results": [
                    {
                        "phone-numbers": "111-111-111"
                    },
                    {
                        "phone-numbers": "222-222-222"
                    },
                    {
                        "phone-numbers": "333-333-333"
                    }
                ]
            },
            "vcards": {
                "results": [
                    {
                        "attr1": "John Doe",
                        "attr2": "john.doe_at_provider.com",
                        "attr3": "john.doe"
                    },
                    {
                        "attr1": "J.D.",
                        "attr2": "jd_at_provider.com",
                        "attr3": "jd"
                    }
                ]
            }
        }
    }
}










The response body for the POST request provides the data, which has been used to start the process.

Introducing the new additional URIs for the BPM Process Start OData service neither changes the service metadata nor breaks the existing (UI) applications, as the initially introduced URIs remain valid. In SAPUI5 applications, which you might develop from now on, you might use the new URIs, which behave in the same way as it was already described in the initial blog post about the BPM Process Start OData service.

You can find more information about the new URIs in the BPM Process Start OData service in the official documentation.

Conclusion

This blog post gave a quick introduction of the new features in the BPM OData services in SAP NetWeaver 7.3 EHP 1 SP 16. Now it is possible to create a custom SAPUI5 application in order to send messages to the intermediate message events. With the support of the new additional URIs in the BPM Process Start OData service, the service consumption becomes easier and more flexible.

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. MEHARUNNISA D

    Hi Vitaly,

    Thank you for explaining so clearly. It helped me alot. Thanks alot.

    I have one query. If i have nested structure it is giving me Invalid data. So will it work for nested structure?

    (0) 

Leave a Reply