This guide provides instructions on how to start SAP BPM Process using BPM API as a Restful Service.

Applies to:

This Document Holds good for all CE 7.3 SP05 onward. This service can be called from UI5 Screen as an Ajax call.

Please note that from 7.31 SP11 onward you can also use the standard BPM OData service to starting processes as mentioned by Christian Loos.

Special Thanks to Christian Loos  for commenting & Andre Backofen for the telling me about the Exact SP form which Starting Process is possible.


Summary:

This guide describes step-by-step how to Start a BPM Process using BPM API as a rest full service.


About Me:

Piyas Kumar Das

As a Sr. Netweaver Consultant, I’ve been undertaking consulting assignments leveraging on my undermentioned NetWeaver skills.

  • Business Process Management (SAP NW BPM)
  • Restful Services using BPM api to be used in UI5 Screens.
  • SAP Web Dynpro Java (SAP WD4J)
  • SAP Business Rules Management (SAP BRMS)
  • SAP Composit Application Framework (SAP CAF)
  • Master Data Management (SAP NW MDM)
  • Enterprise Portal (SAP EP)
  • Services creation using NWDS (SAP EJB)
  • Enterprise SOA

NOTE: Please reffer to this document by Andre Backofen for the version by version Odata Services update Custom UIs with the BPM OData Service


We will be discussing following points in detail in this document –


  1. Adding Libraries.
  2. Setting up the foundation for using Libraries.
  3. Creating Deploy-able Object.
  4. Accessing the methods exposed.
  5. Testing your REST services


Adding Libraries:


Step 1 : Download the Libraries using the below link:

Download Jars.


Step 2 : Create a new DC of type “External Library” and paste the jars into the “libraries” folder of the DC.

/wp-content/uploads/2014/01/1_403029.jpg

Step 3 : Expose the added libraries as public parts of type “Compilation” and “Assembly”. To do that, go to “Component Properties” go to “Public Parts” and right click and select “Manage Entities”. Expand the Archive and select all the Jar’s for both the public parts.

/wp-content/uploads/2014/01/1_403029.jpg

/wp-content/uploads/2014/01/1_403029.jpg

Step 4 : Create an Enterprise Application DC and add the External library DC as a dependency.

/wp-content/uploads/2014/01/1_403029.jpg

Step 5 : In the Enterprise Application DC, create a public part of type “Compilation” and add the compilation type public part from the External library DC as the referenced entity using the “Referenced entities” option in the right click context menu of the public part as shown below. Finally build the DC.

/wp-content/uploads/2014/01/1_403029.jpg

Setting up the foundation for using Library:

Step 1 : Create a new DC of type “Web Module”.

/wp-content/uploads/2014/01/1_403029.jpg

Step 2 : Define a dependency between the Web Module and the library DC. Add only the “api” public part from the External library DC to the Web module DC.

/wp-content/uploads/2014/01/1_403029.jpg

Step 3 : Create 2 packages (1 for Business Objects, 1 for the Restful Services)

/wp-content/uploads/2014/01/1_403029.jpg

Step 4 : Create Business Objects as shown below:


import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Material {
  protected String material;
  protected String industrySector;
  protected String materialType;
  protected String description;
public String getMaterial() {
  return material;
  }
  public void setMaterial(String material) {
  this.material = material;
  }
  public String getIndustrySector() {
  return industrySector;
  }
  public void setIndustrySector(String industrySector) {
  this.industrySector = industrySector;
  }
  public String getMaterialType() {
  return materialType;
  }
  public void setMaterialType(String materialType) {
  this.materialType = materialType;
  }
  public String getDescription() {
  return description;
  }
}









Step 5 : Create a restful service class file and write a code as shown below:


import java.io.StringReader;
import java.net.URI;
import java.util.Iterator;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import bo.Material;
import com.sap.bpm.api.BPMFactory;
import com.sap.bpm.exception.api.BPMException;
import com.sap.bpm.pm.api.ProcessDefinition;
import com.sap.bpm.pm.api.ProcessDefinitionManager;
import com.sap.bpm.pm.api.ProcessStartEvent;
import com.sap.bpm.pm.api.ProcessStartManager;
import com.sap.bpm.tm.api.Status;
import com.sap.bpm.tm.api.TaskAbstract;
import com.sap.bpm.tm.api.TaskDetail;
import com.sap.bpm.tm.api.TaskInstanceManager;
import com.sap.tc.logging.Location;
import commonj.sdo.DataObject;
@Path("/MaterialCreationService")
@Produces({MediaType.APPLICATION_XML})
public class MaterialCreationToRestService {
  private static final Location location = Location.getLocation(MaterialCreationToRestService.class);
  private final String PRE_TASK_URI = "bpm://bpm.sap.com/task-instance/";
  @Path("/startMaterialCreationProcess")
  @POST
  @Produces( { MediaType.APPLICATION_JSON })
  @Consumes( { MediaType.APPLICATION_JSON })
  public String startMaterialCreationProcess(MaterialCreation materialCreation) throws Exception {
  try {
  ProcessDefinitionManager processDefinitionManager = BPMFactory.getProcessDefinitionManager();
  ProcessDefinition processDefinition = processDefinitionManager.getActiveProcessDefinition("demo.sap.com", "mat~create~bpm", "Material_Creation");
  ProcessStartManager processStartManager = BPMFactory.getProcessStartManager();
  Set<ProcessStartEvent> processStartEvents = processStartManager.getProcessStartEvents(processDefinition.getId());
  ProcessStartEvent processStartEvent = processStartEvents.iterator().next();
  DataObject processStartDataObject = processStartManager.createDataObjectForStartEvent(processStartEvent);
  setMaterialCreationToDataObject(materialCreation, processStartDataObject);
  URI processInstanceId = processStartManager.startProcess(processStartEvent, processStartDataObject);
  return processInstanceId +" process successfully started";
  } catch (Exception e) {
  location.debugT("Error while Starting BPM process"+e);
  throw e;
  }
  }
  private void setMaterialCreationToDataObject(MaterialCreation materialCreation, DataObject pDataObject)
  {
  if(materialCreation == null || pDataObject == null)
  return;
  pDataObject.set("Material", materialCreation.getMaterial());
  pDataObject.set("IndustrySector", materialCreation.getIndustrySector());
  pDataObject.set("MaterialType", materialCreation.getMaterialType());
  pDataObject.set("Description", materialCreation.getDescription());
  }
}







  • The Following code is very important as the “vendor name” , “deploy dc name” and “process name” is set in the BPM API./wp-content/uploads/2014/01/1_403029.jpg
  • The “deploy dc name” / “deploy-able DC Name” can be got from:/wp-content/uploads/2014/01/1_403029.jpg


Note : Key points to be noted in this class.

  1. All Plain Old Java objects (POJOs) used as a part of method signature in this class must be annotated with @XMLRootElement
  2. @Path annotation at the class level is used to indicate the URL identifier in which you would like to expose the class
  3. Use the @GET and @POST annotations at the class level to define which methods needs to be exposed how. Typically, @GET is used when the method in the class has to get an existing data from a data source (ex: get details of a customer from DB) and @POST is used when the given data has to be posted / saved to the data source (ex: DB level create, update, delete).
  4. @Path annotation at the method level with the value placed inside “{value}/” is used to either specify the query parameter in the REST service (for ex: Say you need to pass the customer id to the service to get the customer details). Refer method getObjectDetails in the sample class given above.
  5. @Path annotation at the method level with a plain value is used to expose the method name in the REST service (for ex: Say you need to expose an update method to get the object data from UI.) Refer method changeObjectDetails in the sample class given above.
  6. @Produces and @Consumes annotations are used specify what content types the methods in the REST service would produce and consume respectively. Typically for UI5, it can be set to MediaType.APPLICATION_JSON.

Step 6 : open the web.xml file and fill in the relevant sections as shown below.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>mat_create_rest_web</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Mat_Create_Rest_Servlet</servlet-name>
    <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
    <init-param>
      <param-name>jaxrs.serviceClasses</param-name>
      <param-value>rest.converter.MaterialCreationToRestService</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Mat_Create_Rest_Servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
  <security-role>
    <description>Everyone</description>
    <role-name>Everyone</role-name>
  </security-role>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Mat_Create_Rest_Servlet</web-resource-name>
      <url-pattern>*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>Everyone</role-name>
    </auth-constraint>
    <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Demo</realm-name>
  </login-config>
</web-app>







  • <display-name> – Provide the display name you need for the Web Module DC
  • <servlet-name> – any name. For ex: “Vendor “for Vendor master process.
  • <servlet-class> – set it to com.sun.jersey.spi.container.servlet.ServletContainer
  • <param-name> – set it to com.sun.jersey.config.property.packages
  • <param-value> – set it to the package in which you’ve placed the EJBInjectableProvide.java
  • <load-on-startup> – set it to 1
  • <servlet-name> – same name as specified for <servlet-name> under the tag <servlet>
  • <url-pattern> – identifier that you need in the URL of the REST service. Can be any string with a “/” before and after the identifier and a * in the end. Ex: “/rest/*”
  • <description> – set it to Everyone
  • <role-name> – set it to Everyone
  • <web-resource-name> – same name as specified for <servlet-name> under the tag <servlet>
  • <url-pattern> – set it to *
  • <role-name> – set it to Everyone
  • <transport-guarantee> – set it to NONE
  • <auth-method> – set it to BASIC
  • <realm-name> – set it to Demo


Step 7 : Open web-j2ee-engine.xml file and fill in the relevant sections as shown below.


<?xml version="1.0" encoding="UTF-8"?>
<web-j2ee-engine xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="web-j2ee-engine.xsd">
  <spec-version>2.4</spec-version>
  <security-role-map>
            <role-name>Everyone</role-name>
            <server-role-name>Everyone</server-role-name>
      </security-role-map>
      <login-module-configuration>
            <login-module-stack>
                  <login-module>
                        <login-module-name>EvaluateTicketLoginModule</login-module-name>
                        <flag>SUFFICIENT</flag>
                  </login-module>
                  <login-module>
                        <login-module-name>EvaluateAssertionTicketLoginModule</login-module-name>
                        <flag>SUFFICIENT</flag>
                  </login-module>
                  <login-module>
                        <login-module-name>BasicPasswordLoginModule</login-module-name>
                        <flag>REQUISITE</flag>
                  </login-module>
                  <login-module>
                        <login-module-name>CreateTicketLoginModule</login-module-name>
                        <flag>OPTIONAL</flag>
                  </login-module>
            </login-module-stack>
      </login-module-configuration>
</web-j2ee-engine>






Creating Deploy-able Object

Step 1 : Create a DC of type Enterprise Application and add the Web Module DC.

Step 2 : Add the External library wrapper Application DC as a dependency to this Enterprise Application DC as shown below.

/wp-content/uploads/2014/01/1_403029.jpg


Accessing the methods exposed.

You can access the deployed REST services by constructing the URL as per the format given below.

http://<server_name>:<http_port>/<context_root_given_in_application_xml>/<url_pattern_in_web_xml>/<value_of_@Path_in_class>/<value_of_@Path_in_method>

  1. <context_root_given_in_application_xml> is the war file name can be found inside gen folder as shown below:/wp-content/uploads/2014/01/1_403029.jpg
  2. <url_pattern_in_web_xml> is defined inside web.xml as shown below:/wp-content/uploads/2014/01/1_403029.jpg
  3. <value_of_@Path_in_class> is defined inside the java class just above the class definition as shown below: /wp-content/uploads/2014/01/1_403029.jpg
  4. <value_of_@Path_in_method> is defined inside the java class just above the method definition as shown below: /wp-content/uploads/2014/01/1_403029.jpg

Testing your REST services

You can test the created REST services using the POSTMAN for Chrome or Advanced REST client for Chrome.

/wp-content/uploads/2014/01/1_403029.jpg

To report this post you need to login first.

30 Comments

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

  1. srinivas sistu

    Hi Piyas,

    A very nice document with clear explanation of each step. Is this document about “Using REST service to start BPM” or “SAP BRMS in SAP BPM”  (as mentioned in the start of your document) or both?

    Regards,

    SrinivaS

    (0) 
    1. Piyas Kumar Das Post author

      Hi Srinivas,

      It was a typing mistake it only explains how to start a BPM Process using BPM API as a restful service.

      I was also planning to create another documents to create BRMS inside BPM which is still in progress.

      Just one small request can you comment on the correction required in the document & rate the document also.

      Cheers

      Piyas

      (0) 
      1. Jocelyn Dart

        Hi Piyas, if there’s a typo in the original document, then please go back and edit it to save confusion for others.

        Thanks for putting up this document on a very interesting topic.

        Rgds,

        Jocelyn

        (0) 
        1. Piyas Kumar Das Post author

          Hi Jocelyn Dart,

          I have already corrected the typo….thanks for highlighting.

          An appreciation coming from the moderator of the community means a lot to me.

          Just one one small request can you also give me in some pointers so that I could improve the document.

          Cheers

          Piyas

          (0) 
        2. Piyas Kumar Das Post author

          Hi Jocelyn Dart,

          Just wanted to know the following:

          Is there any OData available to get all the task assigned to a specific user?

          is there any OData available to upload and download documents for a task?


          Cheers

          Piyas

          (0) 
  2. Christian Loos

    Hi Piyas,

    well explained.

    Please be aware that we plan to provide a standard BPM OData service for starting processes with the next SP version.

    Regards,

    Christian

    (0) 
    1. Piyas Kumar Das Post author

      Hi Christian,

      Just wanted to know the following:

      Is there any OData available to get all the task assigned to a specific user?

      is there any OData available to upload and download documents for a task?


      Cheers

      Piyas

      (0) 
      1. Christian Loos

        Hi Piyas,

        OData service for getting all tasks of the current user is planned for 7.31 SP12.

        For documents/attachments, there is also an OData service planned but I don’t have a specific timeline.

        Regards,

        Christian

        (0) 
        1. Piyas Kumar Das Post author

          Hi Christian Loos,

          Thanks for the reply have already mentioned you inputs in the document i have created.

          Please do let me know in Which SP the document/attachments is planned.

          Thanks in ahead

          Cheers

          Piyas

          (0) 
  3. Sreenivas Pachva

    Hi Piyas,

    Nice document…I am new to BPM, I was tried with your document in my system,but i am getting error at rest.converter class..i copy and paste code  of the same document but it is showing com.sap.bpm not found..Can you please what i have to do as a prerequisite…

    Thanks

    Sreenivas Pachva

    (0) 
    1. Piyas Kumar Das Post author

      Hi Sreenivas,

      You could have done something wrong in either of the three “vendor name” , “deploy dc name” or “process name” in the code.

      Cheers

      Piyas

      (0) 
  4. wim coremans

    hi

    before i install this, i would like to see the result of a process map.

    ie: start an order, a delivery and an invoice

    any chance to see it?

    wim

    (0) 
  5. Kumar Das

    Hi Piyas,

    I tried out this document it works wonders but was facing some issue initially.

    It would be nice  if you would have given a little insight to the BPM process diagram, WSDL.

    Thanks a lot

    Kumar.

    (0) 
    1. Piyas Kumar Das Post author

      Hi Sunil,

      This is just the first document in the series.

      I have written more documents if you require them you can use them for your help

      Cheers

      Piyas

      (0) 
  6. Bimal Kumar Das

    Hi Piyas,

    Very Elaborative Document. This is fine while we have is a simple structure.

    If we have a complex structure what do we do then?

    Best

    Bimal

    (0) 

Leave a Reply