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

Web service fault handling in NW BPM has always been a bit of unsuccessfully traversed BPM territory. In a solution with lot of reliance on Web Services, the fault handling forms an important part of the overall solution.

I gather there is some mature support provided in later versions of BPM, but for the version we have worked on 7.2SP5, it was very difficult to handle web service faults.

However, to handle these faults, a work around using EJBs can be put in place. This workaround comes with some extra pieces of coding and development, but addresses the issue. In case of external web services or ES web services, this might be bit straight-forward to use EJBs to provide a service wrap. However, for scenarios with MDM WS which does lot of XML import internally, its bit lengthy.

For our solution where there was a lot of reliance on MDM WS, we struggled to handle faults initially, but could do it with EJB wraps later.

Depicting below the scenario to handle MDM WS fault exceptions in NetWeaver BPM.

Scenario:

Let’s consider a simple syndication web service which is called in NW BPM. This automated activity should throw an exception if wrong parameters are supplied and should get handled appropriately.

                                                                                                                                                                                       

Implementation:

1.      Create a simple MDM Syndication WS (TestMDMSynd on MDM table TestSyndicate) using MDM WSgenerator and deploy it. For the scenario, MDM WS with No Authentication is created. Get the WSDL URL from NWA->SOA Management-> Application and Scenario Communication -> Single Service Administration. (You can ensure that created WS is successfully getting executed from WSNavigator)

2.      Create an EJB module project in NWDS.

3.      Right Click on the created EJB project and create new “Session Bean”. Give the class name MDMWSWrapper, package and click Finish.

4.      Create an EAR project in NWDS and give reference of EJB project created above for deploying.

    

5.      In EJB DC, Right click on EJB DC ->Import ->WSDL -> Remote Location/File System-> Give WSDL URL fetched in step 1 and click Finish. This should import the WSDL in EJB project. You can see the imported WSDL in EJB project as

    

6.      In the context menu of the imported root WSDL file, choose Web Services   --> Generate Client, keep the slider at “Deploy Client”, and ensure that correct EAR application is selected.    Choose Next -> Specify JAX-WS customization files and click Finish. This will generate the proxy class that will be used to execute the web service.

    

The generated proxies should be seen in EJB DC as:

7.      Create a method in the class this will be exposed in WS operation using annotation (@WebMethod). This method accepts 4 parameters required for syndication viz. Port name, remote system, destination name and repository name. Also note the annotation (@WebService ) specified before the MDM Class declaring this class as a service.

8.      Create an inner MDMWSTechException class that extends Exception class. This is the type of exception that is thrown when any errors occurs in EJB i.e. MDM WS execution.

The structure of MDM class should be

/**

* Session Bean implementation class MDMWSWrapper

*/

@Stateless

@WebService(serviceName="MDMWSService")

public class MDMWSWrapper {

    /**

     * Default constructor.

     */

    public MDMWSWrapper() {

        // TODO Auto-generated constructor stub

    }

    @WebMethod(operationName="MDMWSMethod")

    public String m_syndicateRecord(@WebParam(name="portName") String portName,

               @WebParam(name="remoteSystem") String remoteSystem,@WebParam(name="destinationName") String destinationName,

               @WebParam(name="repositoryName") String repositoryName) throws MDMWSTechException{}

    class MDMWSTechException extends Exception{

      /**

             *

             */

            private static final long serialVersionUID = 7629109890925239778L;

            public MDMWSTechException(){}

  

      public MDMWSTechException(String message){

            super(message);

      }

    }

}

     

Write down below code in method to invoke MDM operation using generated proxies. The code below specifically sets the parameters for syndication operation. (For this scenario we will hard code the record Id to be syndicated i.e. record with internal ID 1 is being syndicated)

    @WebMethod(operationName="MDMWSMethod")

    public String m_syndicateRecord(@WebParam(name="portName") String portName,@WebParam(name="remoteSystem") String remoteSystem,@WebParam(name="destinationName") String destinationName,@WebParam(name="repositoryName") String repositoryName) throws MDMWSTechException{

      String result = null;

      try{

             // Create a URL pointer to the WSDL location

            URL wsdlLocation = new URL("http://<host name>:<port>/TestSyndPCRWs/HTTPNone?wsdl");

            // Instantiate ProxyClass object with above URL pointer, service name and namespace

        

            TestSyndPCRWs serviceObject = new TestSyndPCRWs(

                        wsdlLocation, new QName("urn:TestSyndPCRWsWsd","TestSyndPCRWs"));

      

            // Get the SEI (Service Endpoint Interface) from the above Service Implementaion Object

            // This SEI can be used to execute the method defined in the Web Service

                   TestSyndPCRWsVi serviceInt = serviceObject.getPort(TestSyndPCRWsVi.class);               

            

                 // Instantiate service parameters and execute the operation

             

                 TestSyndicateID testSyndicateID= new TestSyndicateID();

                 testsyndpcrws.beans.ws.mdm.sap.com.ObjectFactory tpsyndicateFactory = new testsyndpcrws.beans.ws.mdm.sap.com.ObjectFactory();

                 JAXBElement<BigInteger> createRecordID = tpsyndicateFactory.createTestSyndicateIDInternalID(BigInteger.valueOf(1));

                 testSyndicateID.setInternalID(createRecordID);

                                     

                 TestSyndicateSyndicationParams testSyndicateSyndicationParams = new TestSyndicateSyndicationParams();

                 ObjectFactory beansWSFactory = new ObjectFactory();

                 JAXBElement<String> createPortValue = beansWSFactory.createSyndicationParamsBasePort(portName);

                 JAXBElement<String> createRemoteSystemValue = beansWSFactory.createSyndicationParamsBaseRemoteSystem(remoteSystem);

                 testSyndicateSyndicationParams.setPort(createPortValue);

                 testSyndicateSyndicationParams.setRemoteSystem(createRemoteSystemValue);

                 testSyndicateSyndicationParams.getRecordIdentification().add(testSyndicateID);

             

                 RepositoryInformation repositoryInformation = new RepositoryInformation();

                 beans.core.mdm.sap.com.ObjectFactory beansCoreFactory = new beans.core.mdm.sap.com.ObjectFactory();

                 JAXBElement<String> createDestination = beansCoreFactory.createRepositoryInformationDestinationName(destinationName);

                 JAXBElement<String> createRepository = beansCoreFactory.createRepositoryInformationRepositoryName(repositoryName);

                 repositoryInformation.setDestinationName(createDestination);

                 repositoryInformation.setRepositoryName(createRepository);

             

                 SyndicationResponse syndicateResponse =

                   serviceInt.syndicateTestSyndicate(testSyndicateSyndicationParams, repositoryInformation);

             

                 if(syndicateResponse.getExecutionStatus().getValue().getFault().isEmpty())

                   result = " Result "+syndicateResponse.getExecutionStatus().getValue()

                        .getStatus().getValue();

                 else{

                   result = " Result "+"Fault";

                   throw new MDMWSTechException(syndicateResponse.getExecutionStatus().getValue().getFault().get(0).getText().getValue());

                 }

      }

      catch(Exception e){

            throw new MDMWSTechException(e.getMessage());

      }

      return portName;

    }

9.      Deploy the EAR DC. This should also deploy the WS exposing above method. Get the WSDL URL from NWA->SOA Management-> Application and Scenario Communication -> Single Service Administration -> Search for i.e. class name

    

10.  Create a BPM DC with a simple process. All we are going to do is create a single automated activity in the process.

11.  Import the WSDL you created from EJB in BPM DC. Create and assign a service group to the imported WSDL.

12.  Create an automated activity in the process based on the service interface of imported WSDL.

13.  Select the automated activity -> Properties -> Boundary Events -> Add the exception class (MDMWSTechException) we have created in EJB should be seen here.

     

14.  Create a connection from the boundary event and pass it through notification activity. This notification should be sent when there is an exception thrown from MDM WS. To prove the concept we are just sending out the notifications here. In live business scenario we can perhaps invoke Admin Console when MDM WS results in technical exception.

15.  Also map the output from boundary event to local process context. This will give detail about the fault message. This value can be passed in notification activity, so we will be notified about the error details.

 

16.  Build EJB, BPM and deploy. Start the process, Notification should get triggered if any of the supplied parameter is wrong. Otherwise, the process gets completed.

17.  Test the BPM which should send notification on any application fault e.g. wrong port name, table name etc.

The approach works well in the cases where we want to capture faults in MDM web services, however comes with bit of coding. Also this works for synchronous web services.

1 Comment
Labels in this area