Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 

User Story

     SAP NetWeaver BPM is used for implementation of complex business processes that generate a lot of business data while execution. This data is used both for decision making while execution and for the analysis of the business processes.

     In our use case, we want to identify one or many process instances based on the contextual data they carry inside. Contextual data is the data that end-users can think of when they search for a business transaction (process instance).

    So far, business process administrators could identify relevant process instances by filtering the process subject or using process names and other execution data:

    The BPM Reporting API (shipped since SAP NetWeaver 7.3, EhP 1, SP6) provides a new feature of finding the data inside of a reporting data source and then identifying the process instance.

     The BPM Reporting API provides the end-users an opportunity to monitor on their own the process instances of interest. Of course, the users should be aware of the meaning of the business processes and the corresponding data, however, the knowledge of the BPM concepts, in this case, is not a prerequisite. This leads to the decrease of the administrative support.

     One of the possible specific use cases could be as follows: the business process of interest is ordering of products in stock. The data about the orders (e.g., the name of the product, the name the customer, the date of the order) is stored in the reporting data source. Using the BPM Reporting API, one is able to identify the relevant process instances given the name of the product, the name of the customer, or the date of the order.


     In this blog, I would like to give an overview of the functionality provided by the BPM Reporting API as well as give a coding example of the client that uses it. The client is based on SAPUI5. You can find the sources at Code Exchange.


The BPM Reporting API

    The BPM Reporting API is located at com.sap.bpm.reporting.api.  The package provides the classes to access the definition of the reporting data sources deployed in the system and to identify process instances based on the reporting data they carry inside. The access point to the functionality of the API can be obtained by the following Java code:

ReportingDataSourceManager manager = BPMFactory.getReportingDataSourceManager();

    This provides an instance of ReportingDataSourceManager type which allows retrieving information about the reporting data sources deployed in the system, searching for the process instances based on the business data, and querying the corresponding data contained in the reporting data sources. The following UME actions protect the methods of the ReportingDataSourceManager and must be assigned to the role of the user who accesses the corresponding reporting functionality:

Action NameProtected Functionality
SAP_BPM_RDS_ViewAccessing the reporting data sources.
SAP_BPM_RDS_SearchSearching in the contents of the data sources.
SAP_BPM_RDS_QuerySearching and querying the contents of the reporting data sources.

    If the necessary actions are not assigned to the user role a BPMIllegalAccessException will be thrown.

Reporting Data Sources

    A reporting data source deployed in the system is a process model artifact, which persists the process context  information at a certain point in the execution of the business process. It consists of the fields that are represented by the ReportingField interface in the BPM Reporting API. The developers should check whether a reporting field can be used for searching or querying by calling the method isSearchable() of the ReportingField interface. If a field which does not support searching and querying is used while performing these operations a BPMIllegalArgumentException is thrown. The following code snippet could be used to obtain all reporting fields of the reporting data source that can be used for searching:

public List<ReportingField> getDataSourceSearchableFields(URI reportingDataSourceId)
          throws BPMException{
     List<ReportingField> fields = getReportingDataSource(reportingDataSourceId).getFields();
     List<ReportingField> result = new ArrayList<ReportingField>();
     for (ReportingField field : fields) {
          if (!field.isSearchable()) {
               continue;
          }         
          result.add(field);
     }
     return result;
}

Version Concept of the Reporting Data Sources

    If a definition of a reporting data source is changed, a new version of the reporting data source is created during deployment of the business process. The reported data is from now on accumulated in the latest version of the reporting data source. Consequently, the data is split between the subsequent versions of the reporting data source. ReportingDataSourceManager provides access to the single versions of the reporting data sources deployed in the system as well as to aggregations over the versions of the reporting data sources with the same definitions and compatible changes between each other. So, the aggregation could be seen as a reporting data source which contains all the data of the aggregated versions of the definition of the reporting data source and allows searching in this data. The compatible changes of a reporting data source are as follows:

  1. Adding a new reporting field (the field is added to the corresponding aggregating reporting data source).
  2. Removing an existing reporting field (the field remains defined in the corresponding aggregating reporting data source).
  3. Changing the type of an existing reporting field to a compatible type (the most comprehensive type remains defined for the field in the aggregating reporting data source). The example of the compatible change of the reporting field type would be a change from integer to short (the type of the reporting field in the corresponding aggregating reporting data source will remain integer as it covers both integer and short). Another example is the change from short to long (the type of the reporting field in the corresponding aggregating reporting data source will become long). On the other hand, changing the type of the reporting field from, for instance, byte to boolean will be considered as incompatible and the aggregating reporting data source, in this case, will not be created. It is important to mention here also, that the integer type of the reporting field refers to all the decimals and is not equal to int in Java.

Accessing the Reporting Data Sources

    From the programmer’s point of view, there is no difference between the versions of reporting data sources and aggregations over the versions of the reporting data source: they can be accessed via ReportingDataSourceManager and are represented by the ReportingDataSource interface of the BPM Reporting API. Versions and aggregations differ in the patterns of their identifiers.

    A pattern for an identifier of a version of a reporting data source looks as follows:

bpm://bpm.sap.com/reporting-datasource/<Name of the reporting data source version displayed in Visual Composer or in the SAP Business Warehouse system connected to the SAP NetWeaver BPM>

    A pattern for an identifier of an aggregation over the versions of the reporting data source looks as follows:

bpm://bpm.sap.com/reporting-datasource/<DC vendor>/<DC name>/<Name of the reporting data source in the NetWeaver Developer Studio>

    For example,

Version: bpm://bpm.sap.com/reporting-datasource/Order_1346435787

Aggregation: bpm://bpm.sap.com/reporting-datasource/mycompany.com/mydc/myprocess/Order


    It can be seen, that an instance of the type ReportingDataSource represents an aggregation over the versions of the reporting data source if there exists a sign ‘/’ after the “bpm://bpm.sap.com/reporting-datasource/” substring of its identifier. This check can be performed by the following java code:

public boolean isAggregatingDataSource(ReportingDataSource reportingDataSource) {
                    //Common part of the IDs of the reporting data sources
                    //and reporting data source versions
                    final String COMMON_URI_PART = "bpm://bpm.sap.com/reporting-datasource/";
                    String inspectedRdsIdString = reportingDataSource.getId().toString();
                    //Ensure that the inspected string does not end with '/'
                    while(inspectedRdsIdString.endsWith("/")){
                              inspectedRdsIdString = inspectedRdsIdString.substring(0,
                                                                                          inspectedRdsIdString.length() - 1);
                    }
                    //Check if there is still a slash after the common part in the inspected string.
                    return inspectedRdsIdString.indexOf("/",
                                        COMMON_URI_PART.length()) >= 0;
          }

Querying the Contents of the Reporting Data Sources

    The results of the method search(…) of the ReportingDataSourceManager interface are the URI identifiers of the process instances that fit the specified searching conditions. The method query(…) of the ReportingDataSourceManager interface provides access to the contents of the reporting data sources that correspond to the specified process instances. These contents are provided as an instance of type ReportingResultSet of the BPM Reporting API. The following Java code iterates over the contents of the ReportingResultSet:

List<ReportingField> reportingFields = getManager().getDataSourceFields(reportingDataSourceId);
URI processInstanceId;
Timestamp creationTime;
Object fieldValue;
while (reportingResultSet.next()) {
     processInstanceId = reportingResultSet.getProcessInstanceId();
     creationTime = reportingResultSet.getCreationTime();
     //Process process instace id and creation time
     for (ReportingField reportingField : reportingFields) {
          fieldValue = reportingResultSet.getObject(reportingField);
          //Process the field value
     }
}

Exceptions

All the exceptions thrown by the methods of the BPM Reporting API inherit the BPMException class of the BPM API. So, all the methods of the BPM Reporting API can throw BPMIllegalArgumentException (if supplied with an invalid identifier of the reporting data source) and BPMIllegalAccessException (if the user is not granted with the proper UME actions). The following code snippet shows how the exceptions thrown by the methods of the BPM Reporting API could be handled in a custom servlet:

try {
          //Calling the methods of the BPM Reporting API ...
} catch (ReportingDataSourceNotFoundException e) {
          if(e.getCause() instanceof ReportingFieldIncompatibilityException){
                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                              "The reporting data source has been changed in " +
                                   "an incompatible manner and cannot be queried.");
          }else{
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                              "The process DC has not been deployed in the system.");
          }
}  catch (BPMIllegalAccessException e){
          response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                    "The user does not have proper rights to access the requested reporting functionality.");
          return;
} catch(BPMIllegalArgumentException e){
          response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                    "The arguments supplied are incorrect.");
          return;
} catch (ReportingDataSourceSearchException e) {
          response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    "Error occurred while searching in the reporting data source.");
          return;
} catch (ReportingFieldNotFoundException e) {
          response.sendError(HttpServletResponse.SC_BAD_REQUEST,
                    "The reporting field specified is not found in the reporting data source.");
          return;
} catch (ReportingDataSourceQueryException e) {
          response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    "Error occurred while querying the reporting data source.");
          return;
} finally {
          //Releasing resources...
}

Example

    The client of the BPM reporting API provided here as an example (demoweb/WebContent/sapui5client.jsp) is represented by SAPUI5-based user interface and search is performed by AJAX calls of the service servlet (RDSWebServiceSimpleServlet) which utilizes the BPM Reporting API. The page contains the fields for the search term, dropdown boxes to select the reporting data sources of interest deployed in the system, and the fields to specify the optional search parameters as well as the tables where the search results are displayed.

Here goes the screenshot of the provided client:

After deployment, the address of the client page will be http://<host>:<port>/demosearchapp/sapui5client.jsp.

Resources

For further and more detailed information about the functionality of the BPM Reporting API, please, refer to the help documentation.

The example client of the BPM Reporting API can be found at Code Exchange.

1 Comment