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: 
abhijeet_mukkawar
Active Contributor

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”.

    

    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

    

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.

    

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.

    

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.

    

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.

    

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.

    

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

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

    

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

    

    

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.

    

     Map Output of Start event to the newly created DO.

    

    

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

    

    

     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.

    

    

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

    

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>)

    

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

    

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

    

    

     Maintain other configuration and repository parameters for the automated activity.

    

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.

         

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.

         

     You can also see the MDM records status getting updated.

    

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

5 Comments
Labels in this area