Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member182534
Active Participant

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.


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

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.

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

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.

Setting up the foundation for using Library:

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

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.

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

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.
  • The "deploy dc name" / "deploy-able DC Name" can be got from:


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.


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:
  2. <url_pattern_in_web_xml> is defined inside web.xml as shown below:
  3. <value_of_@Path_in_class> is defined inside the java class just above the class definition as shown below:
  4. <value_of_@Path_in_method> is defined inside the java class just above the method definition as shown below:

Testing your REST services

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

31 Comments
Labels in this area