Skip to Content
Introduction

The Mapping Lookup API, introduced in SP13, enables XI developers to call RFCs from user-defined functions and Java mapping programs. However, using the API means handling lower-level details like communicating with the RFC adapter, building the XML request and parsing the XML response. This can lead to programs that contain lots of boilerplate code and are messy and hard to reuse. In this blog entry I outline a a cleaner, more object-oriented solution. I demonstrate the technique by wrapping calls to BAPI_CUSTOMER_GETLIST in an easy-to-use Java class.

Taking an OOP approach

Whenever you call an RFC in a remote system using the Mapping Lookup API, the code that handles the request and response documents is specific to the function module being called. However, other parts of the code are independent of the remote function module, e.g. the code that delivers XML to and receives XML from the RFC adapter. An OOP approach to this situation would be moving the common code to a superclass and keeping the function module specific code in subclasses that extend this superclass. The benefit of this approach is less code duplication and a cleaner separation of responsibilities.

The sample code below consists of three classes: LookupBase, CountryLookup and LookupException. LookupBase is an abstract class that contains the common code. Its abstract methods, buildRequestXml and parseRfcResponse, are specific to the function module being called and must be implemented by all concrete subclasses. CountryLookup extends LookupBase and contains the code that is specific to our requirement, which is looking up a customer’s country of residence by executing BAPI_CUSTOMER_GETLIST. LookupException is an exception indicating that a problem occurred during the lookup.

The sample code

DISCLAIMER: Please note that the following source code is provided for educational purposes only. It is not intended for production use.

LookupBase.java

CountryLookup.java

LookupException.java

Using the CountryLookup class

Using the CountryLookup class in a user-defined function is straightforward:


// First, get a CountryLookup instance.
CountryLookup cl = new CountryLookup();

// Set the Business Service representing
// the remote system.
cl.setService("R3LookupSystem");

// Set the Communication Channel used for
// calling RFCs in the remote system.
cl.setChannel("RFC");

// Set the ID of the customer.
cl.setCustomerId(customerId);

// Execute the RFC in the remote system
// (might throw a LookupException).
try {
    cl.lookup();
} catch (LookupException e) {
    // Your error handling goes here.
}

// Finally, return the customer's
// country of residence.
return cl.getCountry();

If you’d like to write the request and response documents to the trace information (at level 2 = info), add the following line before the call to lookup:


cl.setTrace(container.getTrace());

Rolling your own

Follow these steps if you’d like to create a wrapper class for a different RFC:

         

  1. Create a new subclass of LookupBase
  2.      

  3. Add the instance variables that will hold the information required by the RFC and the information returned by the RFC
  4.      

  5. Add getter and setter methods that grant read/write access to the information required by the RFC
  6.      

  7. Add getter methods that grant read access to the information returned by the RFC
  8.      

  9. Override checkState, refer to CountryLookup for an example
  10.      

  11. Build the request document in method buildRequestXml
  12.      

  13. Parse the response document in method parseRfcResponse, storing the returned information in the appropriate instance variables
  14.      

  15. There is no step 8 🙂

DOM vs SAX

In the example code I use DOM to parse the response document. Keep in mind, though, that DOM may not always be the right choice. With DOM, your parsing code will generally be easier to read and write, but parsing large documents can potentially consume a lot of resources. The reason for this is that an in-memory node tree is built for each document you parse. SAX parsing, on the other hand, requires far less resources. However, the event-driven nature of SAX will generally result in more complex code, since the state of the parsing has to be maintained by the developer.

Further reading

In the above I’ve outlined an OOP approach to Mapping Lookup API code. For a completely different take on how to execute RFCs in remote systems using the Mapping Lookup API, I suggest you take a look at “Easy RFC Lookup From XSLT Mappings Using a Java Helper Class”, written by my colleague Thorsten Nordholm Søbirk.

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Steven De Saeger
    Hi Morten,

    Great example of how to deal with this kind of low-level API handling …

    Keep up the good work and looking forward to moreof this …

    Regards,

    Steven

    (0) 
    1. s. sharma

      hello Morten,

      I am doing one scenario JDBC ->PI – RFC

      i am usinf RFC for BOM uloading. My scenario works fine.

      But as per customer demand . data should flow in encrypted from.

      i added adapter module for encryption and decryption as suggested by william li

      Developing Adapter User-Module to Encrypt XML Elements in Process Integration 7.1

      now i am getting this error

      Message processing failed. Cause: com.sap.engine.interfaces.messaging.api.exception.MessagingException: com.sap.aii.adapter.rfc.afcommunication.RfcAFWException: error while processing message to remote system:com.sap.aii.adapter.rfc.core.client.RfcClientException: could not get functionname from XML requst: com.sap.aii.adapter.rfc.RfcAdapterException: failed to read funtionname from XML document: missing namespace declaration(1)

      Please suggest me how to solve this issue…

      Sandeep Sharma

      (0) 

Leave a Reply