Executing RFC Calls From A NetWeaver Cloud Application
Executing RFC Calls From A NetWeaver Cloud Application
Executing RFC Calls From A NetWeaver Cloud Application
Applies to:
SAP NetWeaver Cloud, SAP Cloud Connector.
Summary
The SAP Cloud Connector enables your applications running in the SAP NetWeaver Cloud to access any kind of on-premise backend system by executing HTTP calls over a secured SSL tunnel. However, the execution of RFC calls from the cloud application into the on-premise network is not yet supported by the current beta version of SAP Cloud Connector. This document describes a possible workaround for making remote function calls from NetWeaver Cloud applications to an ABAP system in the on-premise network via the HTTP-RFC-Switch implemented by the SAP Business Connector. Author: Ulrich Schmidt
Author Bio
Ulrich Schmidt joined SAP in 1998 after working in the field of Computational Algebra at the Department of Mathematics, University of Heidelberg. Initially, he was involved in the development of various products used for the communication between SAP R/3 systems and external components. These products include the SAP Business Connector, which translates SAPs own communications protocol RFC into the standard Internet communications protocols HTTP, HTTPS, FTP, and SMTP, as well as pure RFC-based tools, such as the SAP Java Connector and RFC SDK. Ulrich gained insight into the requirements of real-world communications scenarios by assisting in the setup and maintenance of various customer projects using the above products for RFC and IDoc communications.
scn.sap.com 1
Table of Contents
Prerequisites ....................................................................................................................................................... 3 Customizing ........................................................................................................................................................ 3 Customizing the SAP Business Connector ..................................................................................................... 3 Customizing the SAP Cloud Connector ........................................................................................................ 10 Developing a Sample Servlet ........................................................................................................................... 11 Creating a Destination Pointing to the Business Connector ......................................................................... 11 Creating a Servlet that calls the RFC Function Modules .............................................................................. 12 Related Content ................................................................................................................................................ 17 Copyright........................................................................................................................................................... 18
scn.sap.com 2
Prerequisites
In the following, I assume two components to be installed in the on-premise network: The SAP Cloud Connector. If you havent installed it yet, see https://help.netweaver.ondemand.com/install_configure_scc.html for instructions. The SAP Business Connector. If there is already a Business Connector installation in your landscape (e.g. for exchanging IDocs or XML messages with business partners), you may reuse it for the purpose at hand. If an SAP Business Connector is not yet installed (or if the existing installation is already running at its capacity limits), you can easily install it in a matter of 30min. The Business Connector can be installed on Windows, Linux, AIX, HP-UX and Solaris. In the current setup a good idea would be to install the Business Connector Server component on the same host where you install the SAP Cloud Connector, or on one of the application servers of your SAP backend system, to which you want to connect. (But in general, any host that is accessible from the SAP Cloud Connector and which has access to the SAP backend will do.) The Business Connector Developer component should best be installed directly on your desktop PC or notebook. The necessary software and an installation guide can be downloaded from https://service.sap.com/sbc-download. Note that a one-time registration of your S-User is necessary in order to access that page. I also assume that you have set up your Eclipse IDE and know how to develop web applications on SAP NetWeaver Cloud. If you need instructions for this, please refer to https://help.netweaver.ondemand.com/ Developers Guide, in particular to the chapter Using the On-Demand to On-Premise Connectivity Service in a NetWeaver Cloud Application, which can be found in the document tree under Consuming the Connectivity Service On-Demand to On-Premise Connectivity Service and describes everything we will need in the following. Alternatively to the above documentation, which describes how to create a web application in form of an OSGi bundle, you can also create your application as a pure web application. See the chapter Consuming Connectivity Service for Pure Web Applications for details.
Customizing
Customizing the SAP Business Connector In the Business Connector we need to provide the necessary settings for two kinds of resources: Logon parameters for the SAP backend system(s) to which we want to connect. We can define more than one SAP system in the Business Connector settings, so one Business Connector installation is sufficient, even if we want to connect to several different SAP systems. The RFC-enabled function modules that we want to call from our cloud application. It is also possible to setup the Business Connector in such a way that you can call any function module in a generic way without further customizing on the Business Connector, so that this step is not necessary. But for security reasons in the following I will describe a setup that allows to call only three function modules and nothing else: o BAPI_COMPANY_GETLIST (returns a table) o BAPI_COMPANY_GETDETAIL (returns a structure) o STFC_WRITE_TO_TCPIC (has a table as input) Lets first setup the connection parameters for our SAP system. (For simplicity I will use only one SAP system in this document, but as I said, any number of SAP systems is possible.) After installation of the Business Connector, you can login to it with a standard web browser on port 5555, using Administrator/manage as credentials. Go to the sub-menu Adapters SAP
scn.sap.com 3
On the following screen, choose Add SAP Server and fill in the connection parameters for your SAP system as follows:
scn.sap.com 4
As Name you may choose any name you like, it is only an alias used later for referring to that SAP system logically. However, I usually use the System ID as name, or if my Business Connector is managing connections to several different clients of the same SAP system, I use names like Y55_CLNT800, Y55_CLNT000, etc. The user used for the connection, can be a system user (CPIC user in earlier ABAP system releases) and can have only a minimal set of authorizations. See SAP note 460089 for details on how to setup a SAP user with just enough permissions to call only those three function modules we want to use in the current example. If you want to logon to one particular SAP application server, fill in the fields in the Server Logon section. If you want to use load balancing, leave the Server Logon section empty and fill in the Load Balancing fields instead. The necessary parameters (application server and system number or message server, logon group and system ID) are the same as the ones you would use when logging on to the system via SAPGui. For the more advanced stuff (e.g. if you want to encrypt the RFC connection between Business Connector and SAP system with SNC), refer to the detailed documentation of the SAP Business Connector. Now that we have defined our SAP backend system, lets make the necessary customizing that makes the following three remote-enabled function modules (RFMs) accessible through the Business Connector. As I mentioned above, the following steps are not necessary, if you use generic mechanisms like pub.sap.client:invoke or RFC Outbound Process, but as I want to illustrate a 100% secure example here, well go the extra distance and setup a very, very restricted scenario. Therefore start the Business Connector Developer tool now and logon to the Server using the same credentials as for the logon with the Browser. First create a new Package, in order to separate our test stuff from the other applications that may be running on the BC:
scn.sap.com 5
Lets call the Package NeoSamples. Inside the package create a folder named rfcMaps. Next select SAP Function Interface from the menu, select the name of the SAP server you created in the previous step from the dropdown list (Y55 in my case), enter BAPI_COMPANY_GETDETAIL as function module and press Lookup.
On the next screen click Generate Outbound Map and Next, enter the name companyGetDetail, select the rfcMaps folder we created above and then click Next, Next and Finish. If you want to, you can now test the Outbound Map (to make sure your SAP user has sufficient authorization for that BAPI), or simply close all open popups now with Cancel and Done. Repeat the same steps for the RFMs BAPI_COMPANY_GETLIST and STFC_WRITE_TO_TCPIC. In the end, our package should look like this:
scn.sap.com 6
In the following steps we will bring several independent protection mechanisms into place, which will ensure that only these three pieces of functionality are accessible from the outside world and nothing else. Go back to the browser in which you are still logged in to the BC administration page, and select Security Ports Add Port:
Select webMethods/HTTPS as type, enter 1443 as port and None as client authentication. (Logon via system certificate does currently not work with SAP Cloud Connector 0.9.5. One of the next versions will remove that limitation; then you can select Require Client Certificates here for increased security. For now we will use plain user/password in the cloud application.)
Note: this step requires that you have also set up your Business Connector with an SSL Server Certificate under Security Certificates. If you havent done so, and c reating an SSL Server Certificate is too much effort for you now, you may as well complete this tutorial with a port of type HTTP for now. (Select the type webMethods/HTTP in the Add Port screen above.)
After you have created the 1443 port, click on Edit in the Access Mode column, remove the ten Services that are listed there in the Allow List and then add our three Services in the rfcMaps folder to the Allow List using the Add Folders and Services to Allow List button. The result should look as follows:
scn.sap.com 7
For additional security, you can also use the IP Access settings to setup your Business Connectors ports in such a way, that the host, on which the SAP Cloud Connector runs, has access only to the 1443 port, but to no other port. I wont go into these details now; if you need help with that, please refer to the standard Business Connector documentation (e.g. the Administration Guide and the Security Best Practices Guide). One security measure that we are going to add to the current setup, though, is protecting our three rfcMaps with a dedicated user, that will be used in the cloud application. For this, please go to Security Users and Groups Add and Remove Users and create a user named CloudUser.
scn.sap.com 8
Next create a group named CloudGroup and add the CloudUser to it. Finally go to Security ACLs, create a new ACL lets call it RFCMaps and add the CloudGroup to it. These elements now allow us to protect our three RFC Outbound Maps in such a way that only the CloudUser will be able to execute them: go to Packages Management Browse Folders.
In the next screen click in the ACL column of the rfcMaps folder, change the Access Control field to RFCMaps and save. This completes our setup in the Business Connector.
scn.sap.com 9
Customizing the SAP Cloud Connector I assume that the SAP Cloud Connector is installed and connected to your account in the cloud. Log in to the Cloud Connector and go to the Access Control tab. Think of a fancy name for your Business Connector and then add a Virtual Host pointing to the 1443 port of your Business Connector, e.g.:
Now select the system mapping you just created and add three resources to it as follows:
(If we are sure that no further Services will be added to the rfcMaps Folder, or if we also want to allow access to any further Services in this folder, we could have created only one resource here with the path /invoke/rfcMaps/ and activated the all sub-paths radio button for it.) Now we are ready to execute these three RFMs from a cloud application!
scn.sap.com 10
In order to access the RFC Outbound Maps on our on-premise Business Connector, we need to create a destination that looks as follows:
scn.sap.com 11
Basically you need to remember only three things: The virtual host name you invented for the Business Connector in the Cloud Connectors access control settings (kassandra.troja.com:1443) (Note: If you have decided to use HTTP instead of HTTPS as configured Business Connector port, then the URL should start with http://... accordingly and the port should be a non-443 port.) The Business Connector User that has access to our RFC Outbound Maps (CloudUser) Add an additional property ProxyType=OnPremise. This is important (including correct spelling), as otherwise your Cloud application will later try to resolve kassandra.troja.com out there in the open internet... After you have saved this, the destination is ready to use in your Cloud applications.
Creating a Servlet that calls the RFC Function Modules For the following, you need to download a jar file now, which has classes for the tasks of deserializing & serializing the RFC input and output data and performing the communication with the Business Connector. This jar file is located on the Business Connector homepage: https://service.sap.com/sbc-download Software Updates Software Updates for SAP BC -- release independent NeoSAPBCAdapter.jar Copy this file to your file system and then simply use drag&drop to copy it into the WebContent WEB-INF lib folder of your Dynamic Web Project:
scn.sap.com 12
If you have created your web application as an OSGi bundle, the following additional step is necessary afterwards: open the META-INF folder, double-click on the MANIFEST.MF, open the Runtime tab and add the WebContent/WEB-INF/lib/NeoSAPBCAdapter.jar to the Classpath section. If you look now at the MANIFEST.MF tab again, you should see a comma-separated entry for the Bundle-ClassPath: entry. If you have created a pure web application, you can omit this step. The rest of the tutorial is now probably best explained in terms of source code. Create a new Servlet in your Web Project, similar to the sample Servlets that you already created as part of the samples in the SAP NetWeaver Cloud Documentation. The following code for the doGet() method will illustrate how to use the classes in the NeoRFCAdapter.jar file to easily invoke the three RFMs and access their importing/exporting/tables parameters. One more point that may be noteworthy: if you have to execute multi-step LUWs (e.g. one or more update BAPIs followed by a BAPI_TRANSACTION_COMMIT), you can do so by first executing the Service pub.sap.client:lockSession on the Business Connector, obtaining the Session -Cookie from the response to this call, using that Session-Cookie for the following requests in the sequence and then finally closing the sequence with a request to pub.sap.client:releaseSession. Below you will find some sample source code. In addition to the usual imports, you will need the following ones, which are provided by the NeoSAPBCAdapter.jar:
import import import import com.sap.mw.bc.SAPBCAdapter; com.wm.data.IDataCursor; com.wm.util.Table; com.wm.util.Values;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter responseWriter = response.getWriter(); responseWriter.println("<html><body>"); try {
scn.sap.com 13
// Retrieve the HTTP destination that points to the on-premise // Business Connector HttpClient httpClient = HttpDestinationFactory.getHttpClient("BusinessConnector"); // First we call BAPI_COMPANY_GETLIST and display the table of // available companies: responseWriter.println("<h1>Executing BAPI_COMPANY_GETLIST</h1>"); SAPBCAdapter companyGetList = new SAPBCAdapter(); companyGetList.setSAPBCService("rfcMaps:companyGetList"); // This BAPI does not have any input parameters, so we can execute // it right away: companyGetList.execute(httpClient); /* * It returns a structure named RETURN and a table named * COMPANY_LIST. Let's first check RETURN for possible errors. The * com.wm.util.Values class represents an RFC structure */ Values returnStruct = companyGetList.getExportingParameterAsStruct("RETURN"); if (returnStruct.getString("TYPE").equals("E")) { responseWriter.println("BAPI returned error message: " + returnStruct.getString("MESSAGE")); } else { /* * The call was successful, so let's display the contents of the * COMPANY_LIST table. An RFC table is represented by the class * com.wm.util.Table. */ Table compList = companyGetList.getTablesParameter("COMPANY_LIST"); int rowCount = compList.getRowCount(); responseWriter.print("COMPANY_LIST contains " + rowCount + " lines. Displaying a maximum of 20:<br>"); if (rowCount > 20) rowCount = 20; Values row; responseWriter.println("<table border=\"1\">"); responseWriter.printf("<tr><th>%s</th><th>%s</th></tr>\n", "COMPANY", "NAME1"); for (int i = 0; i < rowCount; ++i) { row = compList.getRow(i); responseWriter.printf("<tr><td>%s</td><td>%s</td></tr>\n", row.getString("COMPANY"), row.getString("NAME1")); } responseWriter.println("</table>"); }
// In the next example we display the details of one company using // BAPI_COMPANY_GETDETAIL. responseWriter.println("<h1>Executing BAPI_COMPANY_GETDETAIL</h1>"); SAPBCAdapter companyGetDetail = new SAPBCAdapter(); companyGetDetail.setSAPBCService("rfcMaps:companyGetDetail"); /*
scn.sap.com 14
* This BAPI has one importing parameter. I know that in my system * there is a company with ID "001000". If necessary, adjust this * value for your environment. */ companyGetDetail.setImportingParameter("COMPANYID", "001000"); companyGetDetail.execute(httpClient); // First we of course check the RETURN structure again. If no // company with ID 001000 exists, it will tell us. returnStruct = companyGetDetail.getExportingParameterAsStruct("RETURN"); if (returnStruct.getString("TYPE").equals("E")) { responseWriter.println("BAPI returned error message: " + returnStruct.getString("MESSAGE")); } else { /* * The call was successful, so let's display the contents of the * COMPANY_DETAIL structure. We could access each of the fields * of COMPANY_DETAIL using the getString("FIELDNAME") method as * in the previous examples, e.g. when accessing the TYPE and * MESSAGE fields of the RETURN structure. But we can also * "loop" over a structure easily and display all of its fields * without having to know their names. This is illustrated in * the following: */ responseWriter.println("<table border=\"1\">"); responseWriter.println( "<tr><th>Field-Name</th><th>Field-Value</th></tr>"); Values companyDetailStruct = companyGetDetail.getExportingParameterAsStruct( "COMPANY_DETAIL"); IDataCursor c = companyDetailStruct.getCursor(); while (c.next()) responseWriter.printf("<tr><td>%s</td><td>%s</td></tr>", c.getKey(), (String) c.getValue()); responseWriter.println("</table>"); }
/* In our final example we use the function module STFC_WRITE_TO_TCPIC to * send a table of type ABAPTEXT into R/3. The contents of the table will * be inserted into the database table TCPIC. */ responseWriter.println("<h1>Executing STFC_WRITE_TO_TCPIC</h1>"); SAPBCAdapter writeToTcpic = new SAPBCAdapter(); writeToTcpic.setSAPBCService("rfcMaps:writeToTcpic"); // First we create a table with a few lines of data: // The ABAPTEXT table has one column with the name LINE. Very strange. String[] cols = {"LINE"}; Table data = new Table(cols); for (int i = 1; i < 6; ++i) { String field = "Some data from the cloud, line " + i; data.addRow(new String[] { field }); } // Now we set the table as input for the FM and push the thing into
scn.sap.com 15
// R/3: writeToTcpic.setTablesParamter("TCPICDAT", data); writeToTcpic.execute(httpClient); responseWriter.println("STFC_WRITE_TO_TCPIC executed successfully. Please logon to R/3, go to SE16 and look for 5 new lines in table TCPIC."); } catch (Exception e) { responseWriter.println("Something went wrong: " + e.toString()); } responseWriter.println("</body></html>"); }
After executing this Servlet on the NetWeaver Cloud Server, the result for table TCPIC in SE16 should look like this:
Note that the above procedure can not only be used to call RFC Outbound Maps on the SAP Business Connector, but also to call arbitrary SAP BC Services, for example Services reading an internal database that was customized in the Business Connectors WmDB p ackage, etc. For more details on SAP BC functionality, please refer to the standard Business Connector documentation at https://service.sap.com/sbcdownload Documentation.
scn.sap.com 16
Related Content
SAP Business Connector Homepage SAP Cloud Connector Downloadpage SAP NetWeaver Cloud Developer Center Executing RFCs from the Cloud -- Discussion Thread
scn.sap.com 17
Copyright
Copyright 2012 SAP AG. All rights reserved. No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP AG. The information contained herein may be changed without prior notice. Some software products marketed by SAP AG and its distributors contain proprietary software components of other software vendors. Microsoft, Windows, Excel, Outlook, and PowerPoint are registered trademarks of Microsoft Corporation. IBM, DB2, DB2 Universal Database, System i, System i5, System p, System p5, System x, System z, System z10, System z9, z10, z9, iSeries, pSeries, xSeries, zSeries, eServer, z/VM, z/OS, i5/OS, S/390, OS/390, OS/400, AS/400, S/390 Parallel Enterprise Server, PowerVM, Power Architecture, POWER6+, POWER6, POWER5+, POWER5, POWER, OpenPower, PowerPC, BatchPipes, BladeCenter, System Storage, GPFS, HACMP, RETAIN, DB2 Connect, RACF, Redbooks, OS/2, Parallel Sysplex, MVS/ESA, AIX, Intelligent Miner, WebSphere, Netfinity, Tivoli and Informix are trademarks or registered trademarks of IBM Corporation. Linux is the registered trademark of Linus Torvalds in the U.S. and other countries. Adobe, the Adobe logo, Acrobat, PostScript, and Reader are either trademarks or registered trademarks of Adobe Systems Incorporated in the United States and/or other countries. Oracle is a registered trademark of Oracle Corporation. UNIX, X/Open, OSF/1, and Motif are registered trademarks of the Open Group. Citrix, ICA, Program Neighborhood, MetaFrame, WinFrame, VideoFrame, and MultiWin are trademarks or registered trademarks of Citrix Systems, Inc. HTML, XML, XHTML and W3C are trademarks or registered trademarks of W3C, World Wide Web Consortium, Massachusetts Institute of Technology. Java is a registered trademark of Oracle Corporation. JavaScript is a registered trademark of Oracle Corporation, used under license for technology invented and implemented by Netscape. SAP, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign, SAP Business ByDesign, and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP AG in Germany and other countries. Business Objects and the Business Objects logo, BusinessObjects, Crystal Reports, Crystal Decisions, Web Intelligence, Xcelsius, and other Business Objects products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of Business Objects S.A. in the United States and in other countries. Business Objects is an SAP company. All other product and service names mentioned are the trademarks of their respective companies. Data contained in this document serves informational purposes only. National product specifications may vary. These materials are subject to change without notice. These materials are provided by SAP AG and its affiliated companies ("SAP Group") for informational purposes only, without representation or warranty of any kind, and SAP Group shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP Group products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty.
scn.sap.com 18