Article
· Jun 26, 2023 9m read

IrisSAP Connector

 



 

Hi Community!


 

Have you ever had to connect IRIS to an SAP system?

I had to face the challenge of connecting InterSystems IRIS with SAP, and once again I was able to verify the grant work made by Intersystems related to adding the possibility of executing native Python code inside IRIS.

 

This feature made the integration very easy thanks to the library pyrfc.

 

With this library, I was able to make calls to a SAP RFC (Remote Function Call) from an IRIS class and receive data from the SAP’s database. 

 

Yet, What is a RFC?

 

RFC is a communication protocol used by SAP. It enables interaction between different SAP or not SAP systems. It also allows external applications to communicate with the SAP system and access the available functions and data within that system.

 

When an RFC is performed, an external application sends a request over the network to the SAP system. The SAP system receives the request, processes it, and returns the requested results or data to the external application.

 

RFC is used for various tasks such as system integration, data transfer, program execution, and retrieving information from SAP.

 

In summary, an RFC in SAP is a remote call to a function or service available in an SAP system that allows communication and data exchange between that system and external systems or applications.


 

Article goal:

I have decided to write this article to describe the steps that I took and the result I received in case it can help someone avoid the struggle.

I have also decided to publish an application in the OpenExchange (link) with almost everything necessary to start the Docker and connect.

 

Why have I said almost everything?. In order to connect with the SAP server, we must download the SAP NetWeaver RFC SDK. Unfortunately, it is protected by copyright, and, for that reason, I can't share the files with you. So, if you want to download that software from the SAP page, you must have an "S" type user.

The OpenExchange application is ready to download the SDK, add some files to it, configure the SAP connection file configuration, and run.

 

Are you interested? Well, let's go!!

 

Steps to download SAP NetWeaver RFC SDK:

 

Once we have our “S” user (If you don’t have any “S” user, ask your SAP system Administrator to provide you with one), we must follow this link.

 

Click on the link with the instructions to download it:

 

 

Then, click on the link to download the files:

 


 

Finally, click on “SAP NW RFC SDK 7.50”





 

Select the Linux  X86_64 Bit version (if you plan to use my OpenExchange application on Docker) and click on the download button:




 

Adding the SAP NetWeaver RFC SDK files to the project:

 

When we have downloaded and unzipped the file, we must copy “nwrfcsdk” folder content into the project’s folder “nwrfcsdk”:

 


 

Explanation of auxiliary files and Dockerfile:

 

The file "nwrfcsdk.conf" must contain the path where the SDK files are to be copied. If you don't intend to change the path in the Dockerfile, there's no need to modify this file.

 

 

The Dockerfile already includes the installation of the necessary libraries required to make the connection:

 

What it does is copy the file “nwrfcsdk.conf”, the content of the folder “nwrfcsdk” and the sapnwrfc.cfg file (I will explain this file later) inside the Docker.

 

Now, it's time to install the Python libraries:

  • pyrfc: which is used to execute the SAP’s RFC 
  • configparser: which is used to read the file with the connection’s parameters of the file sapnwrfc.cfg


 

Configuring the SAP server connection:

 

To connect it with the SAP server, you must add the required information to the file "sapnwrfc.cfg".

 

If you don’t have that info, but you can log in on the SAP server, just follow the steps mentioned below to find out. If you don’t have access to an SAP server, you must ask the SAP Server Administrator to share that info with you.

Getting the SAP server connection data:

Screenshots may vary a bit depending on whether you are using SAP GUI (Windows Users) or SAP GUI for JAVA (macOS and Linux users). In my case, it's SAP GUI for JAVA

 

1 - Enter SAP GUI and select your Server. Then, click on the Connect button:

 

 

2 - Insert your SAP username and password, and press Enter or click on the accept button:

 

3 - Once you have logged in, go to the menu bar and select “System”. Then, select the option “Status” in the dropdown menu:

 


 

In this window, you can obtain the following:

  • The value of the field “Client” for the property “client” of the configuration file. 

 

  • The value of the field “User” for the property “user” of the configuration file. (In this case, my user for logging in to SAP and RFC is the same. However, in production environments, it's recommended to use different users.)

 

  • The value of the field “Host” for the property “ashost” of the configuration file. (It could be a hostname or an IP address)

 

  • In case your user for RFC communication is the same as the one you have utilized for logging in to the SAP system, you have to use the same password for the property "passed" of the configuration file.

 


 

If you have any problems with the connection, check with the SAP system Administrator if the user you have set in the configuration file has the permissions to execute RFC.



 

Once these steps have been taken, we are ready to start!!


 




 

Checking the connection with SAP


 

In order to check the SAP connection, you can run the method TestConnection located on the class RFC.RFCUtil.cls 

ClassMethod TestConnection() [ Language = python ]
{
 try:
   # Import python libraries
   from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
   from configparser import ConfigParser


   # Connect to the SAP Server
   config = ConfigParser()
   config.read('/opt/irisapp/sapnwrfc.cfg')
   params_connection = config._sections['connection']
   conn = Connection(**params_connection)


   # Launch RFC call to STFC_CONNECTION
   result = conn.call('STFC_CONNECTION', REQUTEXT=u'Hello SAP!')


   # Close the connection
   conn.close()


   # Print the result
   print(result)


 except Exception as e:
   print(e)
 }

If everything goes well, you should see in the debug console something like this:

 

 

(If you receive an error please check if the configuration you have written in the configuration file “sapnwrfc.cfg” is correct. )


 

As you can see, the way to call an RFC is easy:

 

1 - Connect to the SAP server

 

2 - Execute the method conn.call(‘name_RFC_to_execute’, RFC_parameters)

 

3 - Close the connection

 

4 - Process the result.

 

In this example, the only parameter admitted is a String, and we send it as a REQUTEXT parameter.

 

Query the data on an SAP table

 

Now we are going to call “RFC_READ_TABLE” which allows us to read an SAP table.

 

In this example, we are going to read all the data in a table:

ClassMethod GetDataTableSFLIGHT() [ Language = python ]
{
  try:
    # Import python libraries
    from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
    from configparser import ConfigParser


    # Connect to the SAP Server
    config = ConfigParser()
    config.read('/opt/irisapp/sapnwrfc.cfg')
    params_connection = config._sections['connection']
    conn = Connection(**params_connection)


    # Define query parameters
    params = {
        'QUERY_TABLE': 'SFLIGHT',
        'DELIMITER': ',',
        'FIELDS': [
            {'FIELDNAME': 'CARRID'},
            {'FIELDNAME': 'CONNID'},
            {'FIELDNAME': 'FLDATE'},
            {'FIELDNAME': 'PRICE'}
        ],
        'OPTIONS': [],
    }


    # Call to función RFC 'RFC_READ_TABLE'
    result = conn.call('RFC_READ_TABLE', **params)


    # Process results
    if 'DATA' in result:
        data = result['DATA']
        fields = result['FIELDS']
       
        # Imprime los nombres de campo
        for field in fields:
            print(field['FIELDNAME'], end='\t')
        print()
       
        # Imprime los datos
        for entry in data:
            values = entry['WA'].split(',')
            for value in values:
                print(value, end='\t')
            print()
    else:
        print('No data found.')


    # Close SAP connection
    conn.close()


  except CommunicationError:
    print("Could not connect to server.")
    raise
  except LogonError:
    print("Could not log in. Wrong credentials?")
    raise
  except (ABAPApplicationError, ABAPRuntimeError):
    print("An error occurred.")
    raise
  except Exception as e:
    print(e)
}


 

For this example, we are passing a structure type as a parameter with the following data:

 

QUERY_TABLE: It's the table name we want to query  (SFLIGHT a default table of flights)

 

DELIMITER: It allows us to select the separator.

 

FIELDSIt's the table columns we want to get. In this case, I'm asking for CARRID (Company ID), CONNID (Connection flight ID), FLDATE (flight date), and PRICE (flight price).
 

Once it has been executed, we can process the answer and print it on the screen or do whatever we want to do with the info... xD.

 

Finally, we close the connection.

 

If everything goes well, you should see something like this in the debug console:




 

Querying data from a table filtering by a field:

It would be a slightly more complex example where we will query the customers table to obtain the data for one customer.

ClassMethod GetDataCustomer(clientSapID As %String) [ Language = python ]
{
 try:
   from pyrfc import Connection, ABAPApplicationError, ABAPRuntimeError, LogonError, CommunicationError
   from configparser import ConfigParser


   config = ConfigParser()
   config.read('/opt/irisapp/sapnwrfc.cfg')
   params_connection = config._sections['connection']
   conn = Connection(**params_connection)


  # Define the parameters
   params = {
     'QUERY_TABLE': 'KNA1',
     'DELIMITER': ',',
     'FIELDS': [{'FIELDNAME': 'KUNNR'}, {'FIELDNAME': 'SORTL'}, {'FIELDNAME': 'TELF1'}],
     'OPTIONS': [{'TEXT': "KUNNR = '" + clientSapID + "'"}],     
 }


 # Call the RFC 'RFC_READ_TABLE' to obtain the data
   result = conn.call('RFC_READ_TABLE', **params)


 # Process the result
   if 'DATA' in result:
     data = result['DATA']
     fields = result['FIELDS']
    
     # Print the fields names
     for field in fields:
         print(field['FIELDNAME'], end='\t')
     print()
    
     # Print the data fields.
     for entry in data:
         values = entry['WA'].split(',')
         for value in values:
             print(value, end='\t')
         print()
   else:
     print('No data found.')


 # Close the connection
   conn.close()


 except CommunicationError:
   print("Could not connect to server.")
   raise
 except LogonError:
   print("Could not log in. Wrong credentials?")
   raise
 except (ABAPApplicationError, ABAPRuntimeError):
   print("An error occurred.")
   raise
 except Exception as e:
   print(e)
}


 


 

Parameters:

 

QUERY_TABLE: It's the table name we want to query (KNA1 is the table of customers in SAP)

 

DELIMITER: It allows us to select the separator.

 

FIELDS: It's the table columns we want to get. In this case, I'm asking for KUNNR (SAP customer ID), SORTL (Customer short name), and TELF1 (Customer phone number).

OPTIONS: It's a filter that we want to apply to the query. In this case, we are filtering by customer ID that is received in the method by parameter.

Once it has been executed, we can process the answer and print it on the screen or do whatever we want to do with it... xD

Finally, close the connection.

 

If everything goes well, you should see something similar to the following:

 

This is only the beginning since thanks to the RFC calls, we can not only do Create, Read, Update, and Delete operations but also execute any SAP (custom or standard) code exposed by one RFC, programs, module functions, etc. RFC is employed not only for reading or writing data but also for launching Programs or functions with it.

I hope that if one day you are faced with any integration between InterSystems and SAP, this article will come in handy for you.

 

If you have any doubts, please write a comment, and I’ll try to help you.

 

Thank you very much for reading!!

 

Link to the application in OpenExchange: https://openexchange.intersystems.com/package/IrisSapConnector

 

Link to the repository: https://github.com/daniel-aguilar-garcia/IrisSapConnector/blob/main/sapnwrfc.cfg

 

Link to the pyrfc library: https://sap.github.io/PyRFC/

Discussion (0)0
Log in or sign up to continue