Skip to Content
Author's profile photo Abhijeet Mukkawar

EJB Mapping Function for MDM Web Service in BPM

Introduction

EJB Mapping functions are instrumental in extending the functionality of standard BPM modelling with custom Java code. This becomes extremely helpful when carrying out complex transformation in BPM where built-in expressions cannot help.

Basic information about creating and using your first EJB mapping function is already available at Create External Mapping Function. The link gives some basic information about creating a concat function. However, many a times we are placed against dealing with complex data type. A small amount of flavour is also added as the external mapping functions works on SDO concepts.

Scope

For understanding and dealing with complex data types we will go through a small example where EJB function can be used to pass list of objects to MDM Update WS.

Here, we will create a simple table in MDM and using MDM web service in BPM updates few of its field. For passing multiple record ids to MDM WS, we will create custom EJB which will break down incoming string of record ids into a list acceptable class in MDM WS.

Create MDM Table

1. Create a table in MDM named “Material”.

     Pic 1.JPG

    Set “Availability” as a Boolean field and True Value – In Stock and False Value – Out Of Stock. In this example, we will try to update this field from BPM.

2.  Make few sample entries in the table

     Pic 2.JPG

Create MDM Update Web Service

1.     3. Create MDM WS on the table created above with Update opertation

    Go To http://<host:port>/mdm/wsgenerator

    Create a new Project. Create a new MDM Web Service on Material table with Update operation.

     Pic 3.JPG

4. Select the fields you want to process from Material table. For this example, we will select only “Availability” field. You can use the same logic to update other fields as well.

     Pic 4.JPG

5.  On next screen, give web service a name and “Generate” it. For example purpose, don’t choose any authentication. However, it’s recommended to use it in live scenarios.

6.  Click Next and deploy to Local host.

     Pic 5.JPG

Create Process DC

1.   7.  Create a process DC. Create a process and import the MDM WS we have just created. You can get the wsdl  from NWA->SOA Management->Single Service Administration

8.  Once imported, create an Automated activity –updateMaterial – referring above created Service Interface.

     Pic 6.JPG

9.  Create a web service to trigger above created process (start_bpmStatChange). This WS will accept stream of record ids and a Boolean “Availability” value for all. Here, all the comma separated records will get updated with same “Availability” value.

     Pic 7.JPG

     Ensure you removed the output parameter of the start web service.

10.  Create a trigger trigger_prc_statChange with the above created service reference.

     Pic 8.JPG

     And assign this to “Event Trigger” property of Start Event.

    

     Pic 9.JPG

11.  Created a DO of type similar to input structure of start WS. This will store the parameters to be passed to EJB function and in turn to MDM update WS.

     Pic 10.JPG

     Map Output of Start event to the newly created DO.

    

     Pic 11.JPG

12.  If you open the Input Mapping of automated activity, you will find the structure it accepts for the ws.

     Pic 12.JPG

    

     You can note that MaterialUpdate element under Material repeats for performing multiple record update.

     We will create an EJB function with the return type MaterialUpdate. This will be a list of elements with record id set to “internalID”

     and value of Availability in “availability”

13.  Create a new EJB function to be used by your business process.

    

     Pic 13.JPG

14.  Mention below signature for the EJB function. Please note to check the “Returns a Collection”

     Pic 14.JPG

15. Note the Return Type – MaterialUpdate. Choose the parameter names. The same parameter name should be used in EJB implementation. For this example, keep the names as “parameter1” and “parameter2”. As of now, ignore the details for JNDI Name. We will fill this up once EJB is built.

Create EJB DC

1.     16.  Now create an EJB DC which will split input string of comma separated record ids into list of “MaterialUpdate” structure.

      Create an EJB with a session bean getIdsAnyType with local interface. This EJB will accept 2 paramters;

     1) string of comma separated record ids,

     2) Availability value for all the record ids.

     Ensure it implements below 2 interfaces. You also need to extend below in Local interface of EJB.

    (You can follow detail steps to create EJB and EAR from the link)

    

     com.sap.glx.mapping.execution.api.function.Function;

     com.sap.glx.mapping.execution.api.invoker.SdoInvoker;

     Now you can implement the needed mapping function method invokeSdo in the bean implementation. The data is passed

     as service data object (SDO) into this method and the result is also returned in this format.

17.  Implement the bean getIdsAnyType as below

    

public class getIdsAnyType implements getIdsAnyTypeLocal, Function, SdoInvoker {

    /**

     * Default constructor.

     */

    public getIdsAnyType() {

        // TODO Auto-generated constructor stub

    }

 

    private static final String PARAMETER1 = “parameter1”;

    private static final String PARAMETER2 = “parameter2”;

    private static final String NAME_PROPERTY_INPUT_PARAMETER1 = SdoRenamingHelper

    .renameXsdElementToSdoProperty(new QName(PARAMETER1), false);

    private static final String NAME_PROPERTY_INPUT_PARAMETER2 = SdoRenamingHelper

    .renameXsdElementToSdoProperty(new QName(PARAMETER2), false);

                /**

     * @see SdoInvoker#invokeSdo(DataObject, SdoInvoker.InvocationContext)

     */

    public DataObject invokeSdo(DataObject inputDo, SdoInvoker.InvocationContext sdoIContext) {

        // TODO Auto-generated method stub

                if (inputDo == null) {

                                throw new IllegalArgumentException(“SourceDO must exist”);

                                }

                               

                if (sdoIContext == null) {

                                throw new IllegalArgumentException(“HelperContext must exist”);

                                }

               

                Type typeInput = inputDo.getType();

                String parameter1 = inputDo.getString(typeInput

                                                .getProperty(NAME_PROPERTY_INPUT_PARAMETER1));

                boolean parameter2 = inputDo.getBoolean(typeInput

                                .getProperty(NAME_PROPERTY_INPUT_PARAMETER2));

               

                String[] recIdsStr = parameter1.split(“,”);

                // output object

                DataObject outputDO = sdoIContext.createOutputDataObject();

               

                String internalId = “internalID”;

                String stAvailability = “availability”;

                String ctEntityIds = “recordIdentification”;

                for (int i = 0; i < recIdsStr.length; i++) {

                                // Create an element on the output object

                                DataObject resultDO = outputDO.createDataObject(0);

                DataObject entityIdsDO = resultDO.createDataObject(ctEntityIds); 

               

                Property stInternalIdProperty = entityIdsDO.getType().getProperty(internalId);

                Property ctEntityIdsProperty = resultDO.getType().getProperty(ctEntityIds);

                Property stAvailabilityProperty = resultDO.getType().getProperty(stAvailability);

               

                entityIdsDO.set(stInternalIdProperty, Integer.parseInt(recIdsStr[i]));

                resultDO.set(stAvailabilityProperty, parameter2);                    

                resultDO.set(ctEntityIdsProperty, entityIdsDO);

               

                                }

                return outputDO;

    }

   

}

          DataObject outputDO = sdoIContext.createOutputDataObject();

     Creates a main output data object.

     In for loop, you keep on creating new element on the main output object.

          outputDO.createDataObject(0);

     This in turn creates a list structured which is returned.

1.   18. Create an EAR and refer the EJB created above. Build the EJB and EAR and deploy EAR.

Update JNDI Name

1.    19.  In the process DC, open the EJB mapping function; enter the JNDI lookup name for the EJB you have created. You can get it from JNDI browser in NWA.

      Alternatively, you can also type the JNDI lookup name directly in the JNDI Name field. The JNDI lookup name is constructed in the following way:

      <SC-Vendor>/<EAR DC-Name>/LOCAL/<Simple EJB Class Name>/<Full Qualified Local Interface Name> (with a / is substituted by a ~ in the <EAR DC-Name>)

     Pic 21.JPG

20.  Go to Input Mapping of automated activity “updateMaterial”.

     Pic 15.JPG

     Open expression editor for MaterialUpdate element. Use the function within a mapping and pass the parameters we received from start event.

     Pic 16.JPG

    

     Maintain other configuration and repository parameters for the automated activity.

     Pic 17.JPG

1.   21. Build and deploy the process DC.

Run and Test Process

1.   22.  Go to NWA -> Configuration Management -> Processes and Tasks -> Process Respository. Find the deployed process and start it.

          Pic 18.JPG

1.    23.  Pass comma separated record ids and Boolean value for “Availability” field. (Note True Value – In stock and False Value – Out Of Stock). With all the records now set to Out Of Stock, on execution the process with true value, selected records availability status should change to In Stock.

          Pic 19.JPG

     You can also see the MDM records status getting updated.

     Pic 20.JPG

1.    24.  In the example above, only single Availability value is provided for all the records. You can add slight variation to this by passing individual value for each record. In that case, start BPM WS should also accept string of values for Availability field for each record. In EJB, you need to tokenize this string as well and map individual value for each MaterialUpdate element.

References

http://help.sap.com/saphelp_nwce72/helpdata/en/19/4e54432c2f44a99619584854bd76ff/frameset.htm

Assigned Tags

      5 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hi Abhijeet,

      Great to see your first blog! Keep up the good work.

      Please follow the BPM space (from the space homepage) so that other BPMers can easily find you.

      Cheers,

      Mariana

      Author's profile photo Abhijeet Mukkawar
      Abhijeet Mukkawar
      Blog Post Author

      Thanks a bunch Mariana!!

      Author's profile photo Jocelyn Dart
      Jocelyn Dart

      Hi Abhijeet, Nice work - a very clear and clean blog.

      Look forward to seeing more from you - I think the MDM use case is a particularly nice one and this is a good example.

      Regards,

      Jocelyn

      Author's profile photo Pradeep Kumar Ganugapenta
      Pradeep Kumar Ganugapenta

      Nice Work Abhijeet...keep doing the same.

      Regards,

      Pradeep

      Author's profile photo Kunal Saggar
      Kunal Saggar

      Good work Abhijeet... The blog is very clear and detailed.