https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/NW-ABAP-Remote-Function-Call-(RFC)-blog-posts.xml SAP Community - NW ABAP Remote Function Call (RFC) 2026-02-23T12:11:15.987061+00:00 python-feedgen NW ABAP Remote Function Call (RFC) blog posts in SAP Community https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your/ba-p/13553737 From zero to hero security coverage with Microsoft Sentinel for your critical SAP security signals – Part 4 2023-07-06T10:42:19+02:00 Martin-Pankraz https://community.sap.com/t5/user/viewprofilepage/user-id/143781 <TABLE border="1"><TBODY><TR><TD><STRONG><span class="lia-unicode-emoji" title=":backhand_index_pointing_right:">👉🏿</span>back to <A href="https://blogs.sap.com/2023/05/22/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your-critical-sap-security-signals-blog-series/" target="_blank" rel="noopener noreferrer">blog series</A> or to GitHub <A href="https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/SAP/Playbooks" target="_blank" rel="noopener nofollow noreferrer">repos</A> with ready-to-run playbooks.</STRONG></TD></TR></TBODY></TABLE><P><SPAN>Dear community,</SPAN><BR /><BR />There are various problematic attack vectors for SAP backends, but only a few are as severe as losing access to the SAP audit log from your security tooling. In <A href="https://blogs.sap.com/2023/05/23/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your-critical-sap-security-signals-part-3/" target="_blank" rel="noopener noreferrer">part 3</A> we discussed malicious deactivation of the SAP audit log. Now, what if the SAP RFC user to collect the audit log info gets locked, deleted, or disabled in any other way too?<BR /><BR />At that point you are <STRONG>fully blind</STRONG> and might <STRONG>not even get the audit-log deactivation message anymore</STRONG> if the attacker is fast.<BR /><BR />Today you will see an automated response flow to <STRONG>deal with that situation</STRONG>. But wait!<BR /><BR />How about regular SAP or Sentinel Collector VM maintenance? How do we <STRONG>distinguish between normal operations and actual attacks?</STRONG><BR /><BR />Stay tuned – <A href="https://learn.microsoft.com/azure/sap/center-sap-solutions/overview" target="_blank" rel="noopener nofollow noreferrer">Azure Center for SAP solutions</A> (ACSS) comes to the rescue<span class="lia-unicode-emoji" title=":dog:">🐕</span>‍🦺<span class="lia-unicode-emoji" title=":rescue_workers_helmet:">⛑</span>️ to wade through the false positives and emphasize the impactful true positives.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-overview.png" border="0" /></P><P>Fig.1 Overview remediation workflow for the Sentinel Collector attack scenario powered by ACSS</P><H1 id="toc-hId-832999307">Cyber-attacks require the quickest possible reaction</H1><P>The <A href="https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/SAP/Playbooks/SAPCollectorRemediate-STD" target="_blank" rel="noopener nofollow noreferrer">provided playbook</A> posts an <A href="https://adaptivecards.io/" target="_blank" rel="noopener nofollow noreferrer">adaptive card</A> to Microsoft Teams with a color-coded message <STRONG>scoring the likelihood of an attack</STRONG> based on the signals coming from <A href="https://learn.microsoft.com/azure/sentinel/sap/sap-solution-log-reference" target="_blank" rel="noopener nofollow noreferrer">the Sentinel Collector for SAP</A>, and the SAP system state. The Azure Center for SAP Solutions provides a set of managed APIs to query such info in a scalable and secure way.<BR /><BR />The playbook is wired to listen to the pre-built Sentinel alert “<A href="https://learn.microsoft.com/en-us/azure/sentinel/monitor-sap-system-health#use-an-alert-rule-template" target="_blank" rel="noopener nofollow noreferrer">SAP - Data collection health check</A>”. But you may customize yourself to whatever scenario you need.<BR /><BR />In the scenario depicted in fig.1 the Sentinel Collector for SAP is healthy while SAP is running fine too.<BR /><BR />That causes the playbook to <STRONG>raise the attack likelihood</STRONG> based on the alert “RFC LOGON FAILURE” to medium. After all there is still a little chance that someone unintentionally performed a breaking user setup change. Up to you to configure this as “high” or “<STRONG>OMG run for your lives</STRONG>” based on how likely you think that is in your landscape.<BR /><BR />See <A href="https://learn.microsoft.com/azure/sap/center-sap-solutions/quickstart-register-system-cli" target="_blank" rel="noopener nofollow noreferrer">here</A> how to <STRONG>register your SAP system with ACSS</STRONG> and be ready for upcoming out of the box integrations.</P><TABLE border="1"><TBODY><TR><TD>In case the <STRONG>Collector or SAP would have been down</STRONG>, the <STRONG>likelihood of attack</STRONG> gets set to <STRONG>low</STRONG> with the suggestion to double check and investigate further through Sentinel, since this likely a planned maintenance or an outage.<BR /><BR />See <A href="https://www.youtube.com/watch?v=IO1cNyAJcYI&amp;t=1510s" target="_blank" rel="noopener nofollow noreferrer">here</A> how to <STRONG>communicate SAP maintenance via Microsoft Teams</STRONG> in an interactive way. <A href="https://youtu.be/IO1cNyAJcYI?t=1667" target="_blank" rel="noopener nofollow noreferrer">Integration with the SharePoint list</A> using the SID known to Sentinel enables you to enhance the presented flow further.<BR /><BR />What else would you like to see here? Reach out or let me know in the comments.</TD></TR></TBODY></TABLE><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-card.png" border="0" /></P><P>Fig.2 Screenshot of adaptive card with Sentinel’s SAP incident in Microsoft Teams</P><P>As per the inferred info from the various sources, the playbook suggests a couple of options to remediate the situation. This is customizable according to your needs.</P><H2 id="toc-hId-765568521">Let the community know what additional remediation paths you would like to see here. Happy to dive deeper.</H2><P>The simplest option addresses the possible process glitch on the Collector VM. Hit the corresponding button (see lower section on above screenshot) to trigger an automatic restart of the VM.</P><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-vm-restart.png" border="0" width="342" height="393" /></P><P>Fig.3 Screenshot of Sentinel Collector VM restart logic<BR /><BR />This suggested remediations (see fig.2) are a natural fit for the upcoming <A href="https://www.microsoft.com/security/business/ai-machine-learning/microsoft-security-copilot" target="_blank" rel="noopener nofollow noreferrer">Microsoft Security Copilot</A>. Will get into details once it gets more widely available.</P><H2 id="toc-hId-569055016">The true power lies in the correlation of multiple signals&nbsp; in addition to the ACSS metadata leading to the event of the SAP Collector being "blinded"</H2><P><IMG src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/07/collector-attack-correlation.png" border="0" /></P><P>Fig.4 Screenshot from Sentinel security video series about multi-staged attacks to SAP</P><P>In the above scenario you can see a sequence of alerts painting the <STRONG>larger picture of the attack</STRONG> from RDP activity to login attempts in various places leading to a successful data download from SAP sending the file to an unknown IP address. In addition to that <A href="https://learn.microsoft.com/defender/threat-intelligence/what-is-microsoft-defender-threat-intelligence-defender-ti" target="_blank" rel="noopener nofollow noreferrer">Microsoft Defender</A> already compiled <STRONG>which attacker group was responsible</STRONG> based on the attack footprint, techniques and tools used.<BR /><BR />See the full video <A href="https://www.youtube.com/watch?v=JcPleCK5AJE&amp;t=652s" target="_blank" rel="noopener nofollow noreferrer">here</A>.</P><H1 id="toc-hId-243458792">Additional automation scenarios</H1><P>Another popular RFC attack vector (<A href="https://wiki.scn.sap.com/wiki/display/Security/Note+3089413+-+Capture-replay+vulnerability+in+SAP+NetWeaver+AS+for+ABAP+and+ABAP+Platform" target="_blank" rel="noopener noreferrer">Capture-Replay vulnerability</A> in NetWeaver AS for ABAP; SAP security Note <A href="https://me.sap.com/notes/3089413/E" target="_blank" rel="noopener noreferrer">3089413</A>) can be addressed like <A href="https://techcommunity.microsoft.com/t5/microsoft-sentinel-blog/detect-capture-replay-vulnerabilities-amp-exploits-with-the/ba-p/3727644" target="_blank" rel="noopener nofollow noreferrer">this</A>. How about blocking the user corresponding to that new SAP system connection? Have a look at <A href="https://blogs.sap.com/2023/05/22/from-zero-to-hero-security-coverage-with-microsoft-sentinel-for-your-critical-sap-security-signals-youre-gonna-hear-me-soar-part-1/" target="_blank" rel="noopener noreferrer">part 1</A> of the series.<BR /><BR />Last weeks publication in the <A href="https://www.heise.de/news/SAP-Authentifizierungs-Konzept-mit-Maengeln-9203990.html" target="_blank" rel="noopener nofollow noreferrer">German SAP security tech press</A> re-inforces the need to deal with RFC vulnerabilites. Would you like to get the recommended security setting change for the function module "<SPAN class="">RFC_TRUSTED_SYSTEM_SECURITY</SPAN>" to be performed automatically from such a workflow? Or would you consider that too high a risk because it could be used to attack from a different angle?<BR /><BR />Part 4 concludes the first wave of my blog series.<BR /><BR />Looking to you now to request additional scenarios and share your own as <A href="https://github.com/Azure/Azure-Sentinel" target="_blank" rel="noopener nofollow noreferrer">Pull Requests</A> on GitHub.</P><H1 id="toc-hId-46945287">Final words</H1><P>That’s a wrap <span class="lia-unicode-emoji" title=":burrito:">🌯</span>today you saw another SAP security automation scenario in action. We <A href="https://github.com/Azure/Azure-Sentinel/tree/master/Solutions/SAP/Playbooks/SAPCollectorRemediate-STD" target="_blank" rel="noopener nofollow noreferrer">deployed a playbook</A> that <STRONG>scores potential attacks to the audit log ingestion pipeline of Microsoft Sentinel</STRONG>. The required signals to determine the severity of the alert are fed by <A href="https://learn.microsoft.com/azure/sap/center-sap-solutions/overview" target="_blank" rel="noopener nofollow noreferrer">Azure Center for SAP solutions</A> to get reliable information about the operational state of SAP.<BR /><BR />In case all involved systems are up and running while only audit log ingestion is impacted, there is a considerable chance for an ongoing attack. The playbook offers<STRONG> pre-configured actions to act immediately directly from Microsoft Teams</STRONG>.<BR /><BR />That <STRONG>brings down the time to action</STRONG> while avoiding to “shoot” from the hip with security incidents when SAP is just down for maintenance. Whooza, whoooza Sentinel. Nothing to worry about 🧘🏻 ☮<BR /><BR />This integration pattern overall is <STRONG>applicable to any SAP API</STRONG>. Got another SAP threat at your hands that needs automatic remediation? Let me know in the comments or reach out directly.<BR /><BR />Cheers<BR />Martin</P> 2023-07-06T10:42:19+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/call-node-js-or-python-functions-from-abap/ba-p/13572286 Call Node.js or Python Functions from ABAP 2023-08-25T16:45:09+02:00 Srdjan https://community.sap.com/t5/user/viewprofilepage/user-id/174007 Node.js rich ecosystem offers plenty of functions and utilities. Using <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">node-rfc</A> server bindings, these assets can be consumed from ABAP, just like standard ABAP functions. SAP Open Source <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">node-rfc</A> connector and <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NW RFC SDK Library</A> make it possible.<BR /> <BR /> For more info check the <A href="https://github.com/SAP/node-rfc/blob/main/doc/usage.md" target="_blank" rel="nofollow noopener noreferrer">node-rfc server documentation</A> and server examples. Example given here is for Node.js platform and it works the same way with Python, using <A href="http://sap.github.io/PyRFC/server.html" target="_blank" rel="nofollow noopener noreferrer">PyRFC</A>.<BR /> <BR /> Background RFC protocol is currently supported for Python and work in progress for Node.js.<BR /> <BR /> Node.js server source code: <A class="Link--primary" href="https://github.com/SAP/node-rfc/blob/main/examples/server-test-blog.mjs" aria-describedby="item-type-10" target="_blank" rel="nofollow noopener noreferrer">server-test-blog.mjs</A><BR /> <BR /> ABAP client source code: <A class="Link--primary" href="https://github.com/SAP/node-rfc/blob/main/examples/zserver_stfc_struct.abap" aria-describedby="item-type-32" target="_blank" rel="nofollow noopener noreferrer">zserver_stfc_struct.abap</A><BR /> <H2 id="toc-hId-963894626">How it works?</H2><BR /> ABAP program can call an ABAP function in Node.js system, over SAP RFC protocol, just like when that function would be in ABAP system. The node-rfc server will route the ABAP RFC call to JavaScript function, registered for serving that ABAP function calls. ABAP function call parameters are automatically transformed to JavaScript and registered JavaScriot function is invoked. After JavaScript function is completed, result is&nbsp; automatically transformed to ABAP format and send back to ABAP client. All standard ABAP RFC call parameters can be used, like ABAP variable (JavaScript variable), ABAP structure (JavaScript "plain" object) or ABAP table (JavaScript array of "plain" objects).<BR /> <BR /> Rather then manually defining ABAP interface the node-rfc server function, the node-rfc can re-use the signature of already existing ABAP function, or empty ABAP function can be created, just to define ABAP function interface for node-rfc server function..<BR /> <BR /> Let try it in real systems, a notebook with Node.js supported LTS release and any new or old ABAP system.<BR /> <H2 id="toc-hId-767381121">ABAP function module signature for Node.js function</H2><BR /> Let use the interface of ABAP function STFC_STRUCTURE, to call JavaScript function which we will create. The STFC_STRUCTURE expects one input structure, IMPORTSTRUCT and returns one variable, the RESPTEXT string and one structure, ECHOSTRUCT. There is also a table parameter RFCTABLE:<BR /> <PRE class="language-abap"><CODE>FUNCTION STFC_STRUCTURE.<BR /> *"----------------------------------------------------------------------<BR /> *"*"Lokale Schnittstelle:<BR /> *" IMPORTING<BR /> *" VALUE(IMPORTSTRUCT) LIKE RFCTEST STRUCTURE RFCTEST<BR /> *" EXPORTING<BR /> *" VALUE(ECHOSTRUCT) LIKE RFCTEST STRUCTURE RFCTEST<BR /> *" VALUE(RESPTEXT) LIKE SY-LISEL<BR /> *" TABLES<BR /> *" RFCTABLE STRUCTURE RFCTEST<BR /> *"----------------------------------------------------------------------</CODE></PRE><BR /> Here is our Node.js function, to be called from ABAP using these parameters:<BR /> <PRE class="language-javascript"><CODE>function my_stfc_structure(request_context, abap_input) {<BR /> // inspect request context<BR /> const attributes = request_context["connection_attributes"];<BR /> console.log(<BR /> "[js] my_stfc_structure context:",<BR /> attributes["sysId"], attributes["client"], attributes["user"], attributes["progName"]);<BR /> console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT);<BR /> <BR /> // prepare response for ABAP client<BR /> const echostruct = abap_input.IMPORTSTRUCT;<BR /> echostruct.RFCINT1 = 2 * echostruct.RFCINT1;<BR /> echostruct.RFCINT2 = 3 * echostruct.RFCINT2;<BR /> echostruct.RFCINT4 = 4 * echostruct.RFCINT4;<BR /> const abap_output = {<BR /> ECHOSTRUCT: echostruct,<BR /> RESPTEXT: `~~~ Node server here ~~~`,<BR /> };<BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> <BR /> // return response data<BR /> return abap_output;<BR /> }</CODE></PRE><BR /> Here is Node.js function call from ABAP client, from ABAP test report:<BR /> <PRE class="language-abap"><CODE>call function 'STFC_STRUCTURE' destination 'NWRFC_SERVER_OS'<BR /> exporting<BR /> importstruct = ls_struct<BR /> importing<BR /> echostruct = ls_struct<BR /> resptext = lv_resp<BR /> tables<BR /> rfctable = lt_table<BR /> exceptions<BR /> communication_failure = 1 message lv_error_message<BR /> system_failure = 2 message lv_error_message.<BR /> </CODE></PRE><BR /> To make this ABAP function call into Node.js work just like standard ABAP function call, following steps shall be done, covered in follow-up sections in detail<BR /> <UL><BR /> <LI>ABAP system: Configure RFC destination for node-rfc server</LI><BR /> <LI>Node.js system: Configure node-rfc server connections to ABAP system</LI><BR /> <LI>Node.js system: Create Node.js function to be called from ABAP and launch the server</LI><BR /> <LI>ABAP system: Call Node.js function</LI><BR /> </UL><BR /> <H2 id="toc-hId-570867616">Configure RFC destination for node-rfc server</H2><BR /> Using transaction SM59 create RFC destination of type TCP/IP connection ("T"), like for example<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-nwrfc_server_os.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destination configuration - technical settings</P><BR /> If bgRFC protocol shall be supported by node-rfc server, configure the basXML serializer option here:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-bgRFC.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destinatin configuration - bgRFC support</P><BR /> <BR /> <H2 id="toc-hId-374354111">Configure node-rfc server connections for ABAP system</H2><BR /> node-rfc server requires two RFC destinations for ABAP system, configured in sapnwrfc.ini file in Node.js system.<BR /> <BR /> The first destination, "MME", is RFC client destination, the node-rfc can use to call ABAP functions. This client connection is used by node-rfc server to obtain ABAP STFC_STRUCTURE function definition, so that node-rfc server can automatically transform ABAP STFC_STRUCTURE call data to JavaScript and vice versa.<BR /> <BR /> The second destination, "MME_GATEWAY", is RFC server destination, open after server is launched and used for listening on ABAP client requests.<BR /> <BR /> <STRONG>sapnwrfc.ini</STRONG><BR /> <PRE class="language-abap"><CODE>DEST=MME<BR /> USER=demo<BR /> PASSWD=welcome<BR /> ASHOST=system51<BR /> SYSNR=00<BR /> CLIENT=620<BR /> LANG=EN<BR /> TRACE=0<BR /> <BR /> DEST=MME_GATEWAY<BR /> GWSERV=sapgw00<BR /> GWHOST=coevi51<BR /> PROGRAM_ID=RFCSERVER<BR /> REG_COUNT=1</CODE></PRE><BR /> <H3 id="toc-hId-306923325">Start node-rfc server</H3><BR /> After <A href="https://github.com/SAP/node-rfc/blob/main/README.md#requirements" target="_blank" rel="nofollow noopener noreferrer">SAP NW RFC SDK binaries</A> are downloaded and installed on your Node.js system, you can create empty folder and install node-rfc<BR /> <PRE class="language-javascript"><CODE>mkdir server<BR /> cd server<BR /> npm init -y<BR /> npm install node-rfc</CODE></PRE><BR /> Now the first server test can be done, to verify ABAP system connections. Create <STRONG>sapnwrfc.ini</STRONG> file in project root directory and create test script, like:<BR /> <PRE class="language-javascript"><CODE>import {RfcLoggingLevel, Server} from "node-rfc";<BR /> <BR /> // Create server instance, initially inactive<BR /> const server = new Server({<BR /> serverConnection: { dest: "MME_GATEWAY" },<BR /> clientConnection: { dest: "MME" },<BR /> // Server options are optional<BR /> serverOptions: {<BR /> logLevel: RfcLoggingLevel.error,<BR /> // authHandler: authHandler,<BR /> },<BR /> });<BR /> <BR /> (async () =&gt; {<BR /> try {<BR /> // Start the server<BR /> await server.start();<BR /> console.log(<BR /> `[js] Server alive: ${server.alive} client handle: ${server.client_connection}`,<BR /> `server handle: ${server.server_connection}`<BR /> );<BR /> } catch (ex) {<BR /> // Catch errors, if any<BR /> console.error(ex);<BR /> }<BR /> })();<BR /> <BR /> // Close the server after 10 seconds<BR /> let seconds = 10;<BR /> <BR /> const tick = setInterval(() =&gt; {<BR /> console.log("tick", --seconds);<BR /> if (seconds &lt;= 0) {<BR /> server.stop(() =&gt; {<BR /> clearInterval(tick);<BR /> console.log("bye!");<BR /> });<BR /> }<BR /> }, 1000);<BR /> </CODE></PRE><BR /> Now open again the NWRFC_SERVER_OS RFC destination using SM59 transaction and find "Connection Test" button<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-connection-test.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destination - connection test</P><BR /> Start your test script in Node.js system and after server alive message press the "Connection Test" button. When RFC connection with ABAP system is working, the output looks like this:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/sm59-connection-test-output.png" height="278" width="517" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">RFC destination connection test output</P><BR /> Now when RFC connectivity is working let create Node.js function and call it from ABAP.<BR /> <H2 id="toc-hId--18672899">Create Node.js function to be called from ABAP and launch the server</H2><BR /> Let add "my_stfc_structure" JavaScript server function, to receive ABAP calls of STFC_STRUCTURE function in Node.js system. Two additions are required in our test script, the server function implementation and registration.<BR /> <BR /> Server function requires nothing special for node-rfc server, it shall implement only "plain" logic to calculate the response for ABAP client. Also promise can be returned.<BR /> <BR /> The first parameter is request_context, just in case the function implementation shall consider it. The second parameter is JavaScript object with ABAP parameters, as defined by ABAP STFC_STRUCTURE function signature.<BR /> <PRE class="language-javascript"><CODE>// Server function<BR /> function my_stfc_structure(request_context, abap_input) {<BR /> const connection_attributes = request_context["connection_attributes"];<BR /> console.log(<BR /> "[js] my_stfc_structure context:",<BR /> connection_attributes["sysId"],<BR /> connection_attributes["client"],<BR /> connection_attributes["user"],<BR /> connection_attributes["progName"]<BR /> );<BR /> console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT);<BR /> const echostruct = abap_input.IMPORTSTRUCT;<BR /> echostruct.RFCINT1 = 2 * echostruct.RFCINT1;<BR /> echostruct.RFCINT2 = 3 * echostruct.RFCINT2;<BR /> echostruct.RFCINT4 = 4 * echostruct.RFCINT4;<BR /> const abap_output = {<BR /> ECHOSTRUCT: echostruct,<BR /> RESPTEXT: `~~~ Node server here ~~~`,<BR /> };<BR /> <BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> return abap_output;<BR /> }<BR /> </CODE></PRE><BR /> The server function is registered using node-rfc server "addFuncion" method, telling the server to route ABAP STFC_STRUCTURE function calls to JavaScript function "my_stfc_structure":<BR /> <PRE class="language-javascript"><CODE> server.addFunction("STFC_STRUCTURE", my_stfc_structure);</CODE></PRE><BR /> ABAP data transformations to/from JavaScript are done by node-rfc server automatically.<BR /> <BR /> Our test script is now ready and the node-rfc server can be started, to serve ABAP client calls:<BR /> <PRE class="language-javascript"><CODE>import { RfcLoggingLevel, Server } from "node-rfc";<BR /> <BR /> // Create server instance, initially inactive<BR /> const server = new Server({<BR /> serverConnection: { dest: "MME_GATEWAY" },<BR /> clientConnection: { dest: "MME" },<BR /> // Server options are optional<BR /> serverOptions: {<BR /> logLevel: RfcLoggingLevel.error,<BR /> // authHandler: authHandler,<BR /> },<BR /> });<BR /> <BR /> // Server function<BR /> function my_stfc_structure(request_context, abap_input) {<BR /> const connection_attributes = request_context["connection_attributes"];<BR /> console.log(<BR /> "[js] my_stfc_structure context:",<BR /> connection_attributes["sysId"],<BR /> connection_attributes["client"],<BR /> connection_attributes["user"],<BR /> connection_attributes["progName"]<BR /> );<BR /> console.log("[js] my_stfc_structure input:", abap_input.IMPORTSTRUCT);<BR /> const echostruct = abap_input.IMPORTSTRUCT;<BR /> echostruct.RFCINT1 = 2 * echostruct.RFCINT1;<BR /> echostruct.RFCINT2 = 3 * echostruct.RFCINT2;<BR /> echostruct.RFCINT4 = 4 * echostruct.RFCINT4;<BR /> const abap_output = {<BR /> ECHOSTRUCT: echostruct,<BR /> RESPTEXT: `~~~ Node server here ~~~`,<BR /> };<BR /> <BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> return abap_output;<BR /> }<BR /> <BR /> (async () =&gt; {<BR /> try {<BR /> // Register server function<BR /> server.addFunction("STFC_STRUCTURE", my_stfc_structure);<BR /> console.log(<BR /> `[js] Node.js function '${my_stfc_structure.name}'`,<BR /> "registered as ABAP 'STFC_STRUCTURE' function"<BR /> );<BR /> // Start the server<BR /> await server.start();<BR /> console.log(<BR /> `[js] Server alive: ${server.alive} client handle: ${server.client_connection}`,<BR /> `server handle: ${server.server_connection}`<BR /> );<BR /> } catch (ex) {<BR /> // Catch errors, if any<BR /> console.error(ex);<BR /> }<BR /> })();<BR /> <BR /> // Close the server after 10 seconds<BR /> let seconds = 10;<BR /> <BR /> const tick = setInterval(() =&gt; {<BR /> console.log("tick", --seconds);<BR /> if (seconds &lt;= 0) {<BR /> server.stop(() =&gt; {<BR /> clearInterval(tick);<BR /> console.log("bye!");<BR /> });<BR /> }<BR /> }, 1000);<BR /> </CODE></PRE><BR /> When test script is started in Node.js system and ABAP test report calls STFC_STRUCTURE function in Node.js system, the test script output looks like:<BR /> <PRE class="language-abap"><CODE>ts-node ci/test/server-test.ts (py3.11.4) ✘ 1 main ◼<BR /> [js] Node.js function 'my_stfc_structure' registered as ABAP 'STFC_STRUCTURE' function<BR /> [js] Server alive: false client handle: 5554800128 server handle: 0<BR /> tick 9<BR /> tick 8<BR /> [js] my_stfc_structure context: MME 620 D037732 ZSERVER_STFC_STRUCT<BR /> [js] my_stfc_structure input: {<BR /> RFCFLOAT: 0,<BR /> RFCCHAR1: '',<BR /> RFCINT2: 2,<BR /> RFCINT1: 1,<BR /> RFCCHAR4: '',<BR /> RFCINT4: 4,<BR /> RFCHEX3: &lt;Buffer 00 00 00&gt;,<BR /> RFCCHAR2: '',<BR /> RFCTIME: '000000',<BR /> RFCDATE: '00000000',<BR /> RFCDATA1: '',<BR /> RFCDATA2: ''<BR /> }<BR /> [js] my_stfc_structure response: {<BR /> ECHOSTRUCT: {<BR /> RFCFLOAT: 0,<BR /> RFCCHAR1: '',<BR /> RFCINT2: 6,<BR /> RFCINT1: 2,<BR /> RFCCHAR4: '',<BR /> RFCINT4: 16,<BR /> RFCHEX3: &lt;Buffer 00 00 00&gt;,<BR /> RFCCHAR2: '',<BR /> RFCTIME: '000000',<BR /> RFCDATE: '00000000',<BR /> RFCDATA1: '',<BR /> RFCDATA2: ''<BR /> },<BR /> RESPTEXT: '~~~ Node server here ~~~'<BR /> }<BR /> tick 7<BR /> tick 6<BR /> tick 5<BR /> ^C</CODE></PRE><BR /> <H2 id="toc-hId--215186404">Calling Node.js function from ABAP</H2><BR /> Here is ABAP test report for calling Node.js function, used in this example<BR /> <PRE class="language-abap"><CODE>*&amp;---------------------------------------------------------------------*<BR /> *&amp; Report ZSERVER_STFC_STRUCT<BR /> *&amp;---------------------------------------------------------------------*<BR /> *&amp;<BR /> *&amp;---------------------------------------------------------------------*<BR /> report zserver_stfc_struct.<BR /> <BR /> data lv_echo like sy-lisel.<BR /> data lv_resp like sy-lisel.<BR /> <BR /> data ls_struct like rfctest.<BR /> data lt_table like table of rfctest.<BR /> <BR /> data lv_error_message type char512.<BR /> <BR /> ls_struct-rfcint1 = 1.<BR /> ls_struct-rfcint2 = 2.<BR /> ls_struct-rfcint4 = 4.<BR /> <BR /> insert ls_struct into table lt_table.<BR /> call function 'STFC_STRUCTURE' destination 'NWRFC_SERVER_OS'<BR /> exporting<BR /> importstruct = ls_struct<BR /> importing<BR /> echostruct = ls_struct<BR /> resptext = lv_resp<BR /> tables<BR /> rfctable = lt_table<BR /> exceptions<BR /> communication_failure = 1 message lv_error_message<BR /> system_failure = 2 message lv_error_message.<BR /> <BR /> if sy-subrc eq 0.<BR /> write: / 'rfcint1:', ls_struct-rfcint1.<BR /> write: / 'rfcint2:', ls_struct-rfcint2.<BR /> write: / 'rfcint4:', ls_struct-rfcint4.<BR /> write: / 'resptext:', lv_resp.<BR /> else.<BR /> write: 'subrc :', sy-subrc.<BR /> write: / 'msgid :', sy-msgid, sy-msgty, sy-msgno.<BR /> write: / 'msgv1-4:', sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4.<BR /> write: / 'message:', lv_error_message.<BR /> exit.<BR /> endif.</CODE></PRE><BR /> When node-rfc server is running and this ABAP report started, the output looks like:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/ABAP-report-output.png" height="312" width="539" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Node.js server call output</P><BR /> <BR /> <H2 id="toc-hId--411699909"><STRONG>Error Handling</STRONG></H2><BR /> In case of error, the server function shall raise exception message and error message will be returned to ABAP, with RFC_EXTERNAL_FAILURE error code.<BR /> <PRE class="language-abap"><CODE> throw new Error("my_stfc_function error");<BR /> <BR /> console.log("[js] my_stfc_structure response:", abap_output);<BR /> return abap_output;<BR /> }</CODE></PRE><BR /> ABAP report output<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/Screenshot-2023-08-25-at-18.22.12.png" height="298" width="505" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">ABAP test report - error</P><BR /> <BR /> <H2 id="toc-hId--608213414">Logging</H2><BR /> When activated, the log is saved in local file: _noderfc.log and above mentioned error looks like:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/08/error-log.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Error log</P><BR /> Enjoy calling Node.js function from ABAP <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span><BR /> <BR /> &nbsp; 2023-08-25T16:45:09+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/abap-rfc-connectivity-from-btp-node-js-buildpack-and-kyma/ba-p/13573993 ABAP RFC connectivity from BTP Node.JS buildpack and Kyma 2023-10-26T16:14:54+02:00 Srdjan https://community.sap.com/t5/user/viewprofilepage/user-id/174007 ABAP RFC connectivity from BTP to ABAP systems is supported by <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/cloud-connector" target="_blank" rel="noopener noreferrer">SAP Cloud Connector</A>, for Java runtime only. This blog describes the RFC connectivity configuration for BTP Node.JS runtime, so that Node.JS BTP applications can consume ABAP RFCs, as described in <EM>Deployment options </EM>section of <A href="https://blogs.sap.com/2023/10/12/powerful-web-applications-with-old-and-new-abap-systems" target="_blank" rel="noopener noreferrer">Powerful web applications with old and new ABAP systems</A> and related blogs.<BR /> <BR /> Our "hello world" example is BTP Node.JS buildpack, with <A href="https://expressjs.com/" target="_blank" rel="nofollow noopener noreferrer">Express</A> server, <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> and <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NW RFC SDK</A>.<BR /> <BR /> The example source code: <A href="https://github.com/SAP-samples/node-rfc-samples/tree/main/integration/noderfc_btp" target="_blank" rel="nofollow noopener noreferrer">SAP-samples/node-rfc-samples//integration/noderfc_btp</A> can be deployed on BTP or tested locally inside <A href="https://github.com/SAP/fundamental-tools/blob/main/docker/btp-cflinuxfs4.Dockerfile" target="_blank" rel="nofollow noopener noreferrer">SAP/fundamental-tools/docker/btp_cflinuxfs4.Dockerfile</A> docker container.<BR /> <BR /> ABAP RFC connectivity from Node.JS on Kyma works practically out of the box, using <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> and <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NW RFC SDK</A> inside docker container. Try <A href="http://SAP/fundamental-tools/blob/main/docker/cflinuxfs4.Dockerfile" target="_blank" rel="nofollow noopener noreferrer">SAP/fundamental-tools/docker/cflinuxfs4.Dockerfile</A> for example.<BR /> <H2 id="toc-hId-963931172">SAP NW RFC SDK on BTP</H2><BR /> ABAP RFC connectivity from Node.JS is provided by <A href="https://github.com/SAP/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> open source, which provides interface to SAP proprietary SAP NW RFC SDK<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/nwrfcsdk-2.png" height="139" width="165" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">SAP NW RFC SDK</P><BR /> SAP NW RFC SDK is <STRONG>not included</STRONG> in <A href="https://github.com/sap/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> because of licensing and SAP Support Portal is the only allowed public distribution channel for SAP NW RFC SDK.<BR /> <BR /> Shared SO libraries are required in runtime and must be registered at operating system level, using LD_LIBRARY_PATH env variable on Linux systems for example. Include files and shared libraries are both required for <A href="https://github.com/sap/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> build and re-build. The node-rfc rebuild can be triggered during BTP deployment, just like for other native Node.JS modules.<BR /> <BR /> Express and SAP/node-rfc are standard NPM packages and BTP deployment is straightforward.<BR /> <H2 id="toc-hId-767417667">Preparation</H2><BR /> We use this <A href="https://github.com/SAP/fundamental-tools/blob/main/docker/btp-cflinuxfs4.Dockerfile" target="_blank" rel="nofollow noopener noreferrer">btp_cflinuxfs4 docker container</A> and standard buildpack structure, with application in <EM>app</EM> folder. To make SAP NW RFC SDK available for <A href="https://github.com/sap/node-rfc" target="_blank" rel="nofollow noopener noreferrer">SAP/node-rfc</A> in cloud application, it shall be copied to app root folder for example:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/10/Screenshot-2023-12-06-at-11.54.27.png" height="124" width="186" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Buildpack</P><BR /> During deployment, native NPM modules like node-rfc may be or must be rebuilt. The re-build process requires SAP NW RFC SDK includes and binaries and <EM>SAPNWRFC_HOME_CLOUD </EM>environment vaiable shell therefore point to SAP NW RFC SDK root folder, just like SAPNWRFC_HOME in on-premise case.<BR /> <BR /> For run-time enablement, the <EM>LD_LIBRARY_PATH</EM> env variable shall point to RFC SDK "lib" folder, like in&nbsp;<A href="https://github.com/SAP-samples/node-rfc-samples/blob/main/integration/noderfc_with_nwrfcsdk/buildpack/manifest.yaml#L7" target="_blank" rel="nofollow noopener noreferrer">manifest.yaml:</A><BR /> <PRE class="language-python"><CODE>---<BR /> applications:<BR /> - name: rfcapp<BR /> stack: cflinuxfs4<BR /> env:<BR /> SAPNWRFC_HOME_CLOUD: /tmp/app/nwrfcsdk<BR /> LD_LIBRARY_PATH: /home/vcap/app/nwrfcsdk/lib</CODE></PRE><BR /> That's all, we are ready for testing.<BR /> <H2 id="toc-hId-570904162">Local test</H2><BR /> <PRE class="language-python"><CODE>$ cd buildpack/app<BR /> $ export SAPNWRFC_HOME=`pwd`/nwrfcsdk<BR /> $ export LD_LIBRARY_PATH=$SAPNWRFC_HOME/lib<BR /> $ npm install<BR /> $ node .<BR /> <BR /> node .<BR /> HOME<BR /> /home/www-admin<BR /> <BR /> SAPNWRFC_HOME<BR /> /home/www-admin/src/sap/node-rfc-samples/integration/noderfc_with_nwrfcsdk/buildpack/app/nwrfcsdk<BR /> <BR /> SAPNWRFC_HOME files:<BR /> ["include","lib","package.json"]<BR /> <BR /> LD_LIBRARY_PATH<BR /> <BR /> <BR /> node-rfc<BR /> {<BR /> "platform": {<BR /> "name": "linux",<BR /> "arch": "x64",<BR /> "release": "6.4.16-linuxkit"<BR /> },<BR /> "env": {<BR /> "SAPNWRFC_HOME": "/home/www-admin/src/sap/node-rfc-samples/integration/noderfc_with_nwrfcsdk/buildpack/app/nwrfcsdk",<BR /> "RFC_INI": ""<BR /> },<BR /> "versions": {<BR /> "node": "18.18.2",<BR /> "acorn": "8.10.0",<BR /> "ada": "2.6.0",<BR /> "ares": "1.19.1",<BR /> "brotli": "1.0.9",<BR /> "cldr": "43.1",<BR /> "icu": "73.2",<BR /> "llhttp": "6.0.11",<BR /> "modules": "108",<BR /> "napi": "9",<BR /> "nghttp2": "1.57.0",<BR /> "nghttp3": "0.7.0",<BR /> "ngtcp2": "0.8.1",<BR /> "openssl": "3.0.10+quic",<BR /> "simdutf": "3.2.14",<BR /> "tz": "2023c",<BR /> "undici": "5.26.3",<BR /> "unicode": "15.0",<BR /> "uv": "1.44.2",<BR /> "uvwasi": "0.0.18",<BR /> "v8": "10.2.154.26-node.26",<BR /> "zlib": "1.2.13.1-motley"<BR /> },<BR /> "noderfc": {<BR /> "version": "3.3.0",<BR /> "nwrfcsdk": {<BR /> "major": 7500,<BR /> "minor": 0,<BR /> "patchLevel": 12<BR /> }<BR /> }<BR /> }</CODE></PRE><BR /> <H3 id="toc-hId-503473376">BTP Deployment</H3><BR /> When all works fine, let deploy<BR /> <PRE class="language-abap"><CODE>$ cd buildpack<BR /> $ cf push<BR /> Pushing app rfcapp to ...<BR /> Uploading files...<BR /> Instances starting....<BR /> Instances starting...<BR /> <BR /> name: rfcapp<BR /> requested state: started<BR /> routes: rfcapp.cfapps.eu10.hana.ondemand.com<BR /> last uploaded: Thu 26 Oct 15:46:54 CEST 2023<BR /> stack: cflinuxfs4<BR /> buildpacks: <BR /> name version detect output buildpack name<BR /> <A href="https://github.com/cloudfoundry/nodejs-buildpack#v1.8.18" target="test_blank" rel="nofollow noopener noreferrer">https://github.com/cloudfoundry/nodejs-buildpack#v1.8.18</A> 1.8.18 nodejs nodejs<BR /> <BR /> type: web<BR /> sidecars: <BR /> instances: 1/1<BR /> memory usage: 128M<BR /> start command: npm run start:btp<BR /> state since cpu memory disk logging details<BR /> #0 running 2023-10-26T13:47:09Z 0.0% 54.9M of 128M 231.8M of 1G 0/s of unlimited </CODE></PRE><BR /> The app test route <A href="https://rfcapp.cfapps.eu10.hana.ondemand.com/" target="_blank" rel="nofollow noopener noreferrer"><STRONG></STRONG></A><A href="https://rfcapp.cfapps.eu10.hana.ondemand.com" target="test_blank" rel="nofollow noopener noreferrer">https://rfcapp.cfapps.eu10.hana.ondemand.com</A>/ shows the same result as on premise test:<BR /> <PRE class="language-abap"><CODE>HOME /home/vcap/app SAPNWRFC_HOME /home/vcap/app/node_modules/nwrfcsdk<BR /> SAPNWRFC_HOME files: ["include","lib","package.json"]<BR /> LD_LIBRARY_PATH /home/vcap/app/node_modules/nwrfcsdk/lib<BR /> node-rfc { "platform": { "name": "linux", "arch": "x64", "release": "6.2.0-33-generic" }, "env": { "SAPNWRFC_HOME": "/home/vcap/app/node_modules/nwrfcsdk", "RFC_INI": "" }, "versions": { "node": "18.18.2", "acorn": "8.10.0", "ada": "2.6.0", "ares": "1.19.1", "brotli": "1.0.9", "cldr": "43.1", "icu": "73.2", "llhttp": "6.0.11", "modules": "108", "napi": "9", "nghttp2": "1.57.0", "nghttp3": "0.7.0", "ngtcp2": "0.8.1", "openssl": "3.0.10+quic", "simdutf": "3.2.14", "tz": "2023c", "undici": "5.26.3", "unicode": "15.0", "uv": "1.44.2", "uvwasi": "0.0.18", "v8": "10.2.154.26-node.26", "zlib": "1.2.13.1-motley" }, "noderfc": { "version": "3.3.0", "nwrfcsdk": { "major": 7500, "minor": 0, "patchLevel": 12 } } }</CODE></PRE><BR /> <H2 id="toc-hId-177877152">Connectivity</H2><BR /> With RFC connectivity enabled in Node.JS on BTP, WS-RFC connection parameters and SAP Business Connector or Cloud Connector can be used for RFC connections to ABAP systems.<BR /> <BR /> &nbsp; 2023-10-26T16:14:54+02:00 https://community.sap.com/t5/technology-blog-posts-by-members/securing-external-rfc-connections-including-certificate-based/ba-p/13575027 Securing external RFC connections, including certificate-based authentication 2023-12-07T09:18:50+01:00 L_Skorwider https://community.sap.com/t5/user/viewprofilepage/user-id/172246 In today's world of cyber-attacks and data leaks, security and encryption should be an absolute priority for any IT organisation. However, experience shows that this is not always the case. Mechanisms that bring security are still often seen as making work difficult and challenging to implement. The fact that a program was configured years before and there was never a problem is used as an excuse not to make changes. This is a very incorrect approach that can have serious consequences.<BR /> <BR /> In this post, I will cover a topic perhaps quite niche for the SAP Basis administrator - securing connections from external non-SAP programs. An aspect that is often overlooked due to a gap in accountability. On the one hand, this is sometimes seen as outside the Basis scope. On the other hand, programs are sometimes configured by third party vendors not necessarily interested in the security of our system. I will try to show what we, as Basis administrators, can do to make the connection more secure.<BR /> <H1 id="toc-hId-834899173">Scope of consideration</H1><BR /> In this post I will try to consider what mechanisms we can use to make an external connection secure. Of course, SNC/SSL-based encryption will be the focus as usual, but I will not limit myself to this technical aspect alone. As usual, I will also touch on topics that are on the borderline of responsibilities or even outside the typical scope of Basis, but important for understanding how the various mechanisms work.<BR /> <BR /> I will discuss the topics of encryption, authentication using an SSL certificate, level of trust in a foreign CA, permissions, limiting network traffic. I will base my analysis on example programs from the <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">SAP NetWeaver RFC SDK</A>. I originally wanted to write my own simple program, but as Basis administrators we usually secure existing software and connections, so this is a more representative example.<BR /> <H1 id="toc-hId-638385668">Environment preparation</H1><BR /> <H2 id="toc-hId-570954882">SAP server side</H2><BR /> My test environment is <A href="https://blogs.sap.com/2023/07/31/abap-platform-trial-1909-available-now/" target="_blank" rel="noopener noreferrer">ABAP Platform Trial 1909</A>, based on S/4HANA 1909. The system is not the youngest, nor is it the oldest, but in the field of RFC connection security, not that much has changed over the years. So most of the insights will be valid for both older and younger systems.<BR /> <BR /> The system has already been prepped for SNC and certificate-based authentication. I described this in my previous post "<A href="https://blogs.sap.com/2023/11/23/sap-gui-single-sign-on-based-on-ssl-certificates-and-snc/" target="_blank" rel="noopener noreferrer">SAP-GUI Single Sign-On based on SSL certificates and SNC</A>", so I won't repeat that part.<BR /> <H2 id="toc-hId-374441377">Client side</H2><BR /> For the purpose of presenting the client program, I prepared a completely fresh Debian Linux system version 12. The <EM>rfcuser</EM> user was also created, in the context of which we will run the program that connects to the SAP server. Of course, you can use another Linux distribution as well, or even Windows, and the results will be similar.<BR /> <H1 id="toc-hId-48845153">SAP NetWeaver RFC SDK</H1><BR /> SAP Note 2573790 describes where to get the library and briefly describes the installation process. I assume you can download it yourself from the Software Download Center, and I will describe the simplest installation method in a moment. I get two files, which I decompress in the <EM>rfcuser</EM> home directory.<BR /> <PRE><CODE>rfcuser@sandboxn100:~$ <STRONG>unzip nwrfc750P_12-70002752.zip</STRONG><BR /> <BR /> Archive: nwrfc750P_12-70002752.zip<BR /> <BR /> creating: nwrfcsdk/<BR /> <BR /> creating: nwrfcsdk/bin/<BR /> <BR /> inflating: nwrfcsdk/bin/rfcexec<BR /> <BR /> inflating: nwrfcsdk/bin/startrfc</CODE></PRE><BR /> [...]<BR /> <PRE><CODE>inflating: nwrfcsdk/lib/libsapnwrfc.so<BR /> <BR /> inflating: nwrfcsdk/lib/libsapucum.so<BR /> <BR /> inflating: SIGNATURE.SMF<BR /> <BR /> rfcuser@sandboxn100:~$ <STRONG>unzip nwrfc750P12HF_2-70002752.zip</STRONG><BR /> <BR /> Archive: nwrfc750P12HF_2-70002752.zip<BR /> <BR /> inflating: libsapnwrfc.so<BR /> <BR /> rfcuser@sandboxn100:~$ <STRONG>mv libsapnwrfc.so nwrfcsdk/lib/</STRONG></CODE></PRE><BR /> All files are located in <EM>nwrfcsdk</EM> folder. Next step is adding the folder to <EM>LD_LIBRARY_PATH</EM> environment variable. I can do this for current session, but to make this permanent, I add this to <EM>.profile</EM> file located in the user's home directory.<BR /> <PRE><CODE>export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/nwrfcsdk/lib</CODE></PRE><BR /> <H1 id="toc-hId--147668352">SAP user</H1><BR /> I plan to establish a connection from an external program to my SAP system to perform some operations. It is easy to guess that I will need a user on the SAP system side to do this. So I'm creating an RFC user that the external program will use for operations on the system. I give it the top-secret password <EM>secure123</EM>, just for the purpose of this presentation, to keep things simple.<BR /> <BR /> In addition to filling in basic user data, I set up the type to <EM>system</EM> or <EM>communication</EM>. In this case, it doesn't matter much. I leave the rest of the data default, including the lack of authorizations, because I'll come back to that in the next step.<BR /> <H1 id="toc-hId--344181857">The first, unsecured connection</H1><BR /> Together with the SDK library, we get two sample programs - <EM>rfcexec</EM> and <EM>startrfc</EM>. <EM>Rfcexec</EM> connects to the SAP gateway and waits for incoming commands from the SAP system. I leave it for another occasion for now and will focus on <EM>startrfc</EM>.<BR /> <BR /> The program connects to SAP and execute one of two function modules, related to EDI or display system information. In fact, I will focus on the last function today. The <EM>-i</EM> switch is responsible for calling it.<BR /> <BR /> Let's call the program:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ ./startrfc -h sandbox -s 00 -u rfcuser -p secure123 -c 001 -i<BR /> Error: No RFC authorization for function module RFCPING.</CODE></PRE><BR /> <EM>Sandbox</EM> is my SAP server hostname <EM>00</EM> is SAP instance number. <EM>001</EM> is a productive client.<BR /> <BR /> Error is expected. In general connection is successful, because program reached checking authorization phase.<BR /> <H1 id="toc-hId--540695362">The principle of least privilege</H1><BR /> Indisputably, the principle of least privilege is one of the most important elements of security and an absolute must when it comes to external connections. Keep in mind that a system is only as secure as its weakest component. Even if you secure your SAP system perfectly, an intrusion into a server independent of you that has rights to connect to SAP with a high level of privilege could result in data leakage or even damage to the system. So you should keep the level of RFC user privileges at the minimum level needed to operate. In fact, this should obviously apply to all users. However, for technical users, this rule is more often ignored for some reason. Do we trust programs more than people?<BR /> <BR /> That's why I didn't give the <EM>RFCUSER</EM>&nbsp;any authorization at the beginning, and now I will build it from scratch. I check what the <EM>SU53</EM> transaction reports for this user by selecting <EM>Authorization Values</EM> / <EM>Other User</EM> from the menu.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/su53-rfcuser.png" /></P><BR /> Apparently, the system first checked whether the user had access to the <EM>RFCPING</EM> function module. Since access was not explicitly granted, so the permissions for the entire <EM>SYST</EM> function group were also checked. Since I am very strict about permissions, I will build a role with minimal privileges in the <EM>PFCG</EM> tranaction.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/pfcg-rfc-user-role.png" /></P><BR /> I added this role to RFCUSER and repeated the connection test.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -u rfcuser -p secure123 -c 001 -i</STRONG><BR /> SAP System ID: A4H<BR /> SAP System Number: 00<BR /> Partner Host: vhcala4hci<BR /> Own Host: sandboxn100<BR /> Partner System Release: 754<BR /> Partner Kernel Release: 777<BR /> Own Release: 753<BR /> Partner Codepage: 4103<BR /> Own Codepage: 4103<BR /> User: RFCUSER<BR /> Client: 001<BR /> Language: E<BR /> </CODE></PRE><BR /> This time the connection is fully successful and I get system information. Authorization is sufficient.<BR /> <H1 id="toc-hId--737208867">Certification authority</H1><BR /> At this point it is worth saying a few words about how my system is configured. This is, in fact, already described in my <A href="https://blogs.sap.com/2023/11/23/sap-gui-single-sign-on-based-on-ssl-certificates-and-snc/" target="_blank" rel="noopener noreferrer">previous post</A>, but it doesn't do any harm to remind you of the basic information. The main certificate authority <EM>(OU=Security)</EM> signed the certificates of intermediate authorities - for servers <EM>(OU=Servers)</EM> and for users <EM>(OU=Users)</EM>. The SAP server certificate was issued by the first one.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/strust-certificates.png" /></P><BR /> It's clear that the simplest solution would be to issue a certificate by an existing certification authority, but that would simplify our considerations a bit too much. Instead, I will assume that the certificate was issued by a completely independent group of certification authorities. So I will add three new to the existing ones, marked in blue in the diagram.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/ca-structure.png" /></P><BR /> I won't focus on details, because you can go through this proces in my previous post, but let's go to the process of CAs creation and issuing RFCUSER's certificate. In practice, SAP administrators are usually not responsible for this part, so if you are not interested in issuing certificates, you can skip without hesitation to the next chapter.<BR /> <BR /> Root CA key creation:<BR /> <PRE><CODE>openssl genrsa -out AnotherRootCA/anotherca.key.pem 4096</CODE></PRE><BR /> Certificate generation:<BR /> <PRE><CODE>openssl req -x509 -sha256 -new -nodes -key AnotherRootCA/anotherca.key.pem -days 3650 -out AnotherRootCA/anotherca.cert.pem<BR /> You are about to be asked to enter information that will be incorporated<BR /> into your certificate request.<BR /> What you are about to enter is what is called a Distinguished Name or a DN.<BR /> There are quite a few fields but you can leave some blank<BR /> For some fields there will be a default value,<BR /> If you enter '.', the field will be left blank.<BR /> -----<BR /> Country Name (2 letter code) [AU]:PL<BR /> State or Province Name (full name) [Some-State]:kuj-pom<BR /> Locality Name (eg, city) []:<BR /> Organization Name (eg, company) [Internet Widgits Pty Ltd]:AnotherCompany<BR /> Organizational Unit Name (eg, section) []:Trustworthy<BR /> Common Name (e.g. server FQDN or YOUR name) []:Another Root CA<BR /> Email Address []:</CODE></PRE><BR /> Intermediate CA key:<BR /> <PRE><CODE>openssl genrsa -out intermediateAppsCA/interApps.key.pem 4096</CODE></PRE><BR /> Certificate signing request:<BR /> <PRE><CODE>openssl req -key intermediateAppsCA/interApps.key.pem -new -sha256 -out intermediateAppsCA/interApps.csr.pem<BR /> You are about to be asked to enter information that will be incorporated<BR /> into your certificate request.<BR /> What you are about to enter is what is called a Distinguished Name or a DN.<BR /> There are quite a few fields but you can leave some blank<BR /> For some fields there will be a default value,<BR /> If you enter '.', the field will be left blank.<BR /> -----<BR /> Country Name (2 letter code) [AU]:PL<BR /> State or Province Name (full name) [Some-State]:kuj-pom<BR /> Locality Name (eg, city) []:<BR /> Organization Name (eg, company) [Internet Widgits Pty Ltd]:AnotherCompany<BR /> Organizational Unit Name (eg, section) []:Apps<BR /> Common Name (e.g. server FQDN or YOUR name) []:Intermediate Apps CA<BR /> Email Address []:<BR /> <BR /> Please enter the following 'extra' attributes<BR /> to be sent with your certificate request<BR /> A challenge password []:*******<BR /> An optional company name []:</CODE></PRE><BR /> Certificate signature by the new root CA:<BR /> <PRE><CODE>openssl x509 -req -in intermediateAppsCA/interApps.csr.pem -days 3650 -CA AnotherRootCA/anotherca.cert.pem -CAkey AnotherRootCA/anotherca.key.pem -CAcreateserial -out intermediateAppsCA/interApps.cert.pem<BR /> Certificate request self-signature ok<BR /> subject=C = PL, ST = kuj-pom, O = AnotherCompany, OU = Apps, CN = Intermediate Apps CA</CODE></PRE><BR /> RFCUSER key creation:<BR /> <PRE><CODE>openssl genrsa -out intermediateAppsCA/rfcuser.key.pem 4096</CODE></PRE><BR /> Certificate signing request:<BR /> <PRE><CODE>openssl req -key intermediateAppsCA/rfcuser.key.pem -new -sha256 -out intermediateAppsCA/rfcuser.csr.pem<BR /> You are about to be asked to enter information that will be incorporated<BR /> into your certificate request.<BR /> What you are about to enter is what is called a Distinguished Name or a DN.<BR /> There are quite a few fields but you can leave some blank<BR /> For some fields there will be a default value,<BR /> If you enter '.', the field will be left blank.<BR /> -----<BR /> Country Name (2 letter code) [AU]:PL<BR /> State or Province Name (full name) [Some-State]:kuj-pom<BR /> Locality Name (eg, city) []:<BR /> Organization Name (eg, company) [Internet Widgits Pty Ltd]:AnotherCompany<BR /> Organizational Unit Name (eg, section) []:<BR /> Common Name (e.g. server FQDN or YOUR name) []:RFCUSER<BR /> Email Address []:<BR /> <BR /> Please enter the following 'extra' attributes<BR /> to be sent with your certificate request<BR /> A challenge password []:********<BR /> An optional company name []:</CODE></PRE><BR /> <EM>Client.cnf</EM> for client certificates:<BR /> <PRE><CODE>nsCertType = client<BR /> extendedKeyUsage = clientAuth</CODE></PRE><BR /> Certificate signing:<BR /> <PRE><CODE>openssl x509 -req -days 365 -in intermediateAppsCA/rfcuser.csr.pem -sha256 -CA intermediateAppsCA/interApps.cert.pem -CAkey intermediateAppsCA/interApps.key.pem -CAcreateserial -out intermediateAppsCA/rfcuser.crt.pem -extfile intermediateAppsCA/client.cnf<BR /> Certificate request self-signature ok<BR /> subject=C = PL, ST = kuj-pom, O = AnotherCompany, CN = RFCUSER</CODE></PRE><BR /> Export certificate to PKCS12 format:<BR /> <PRE><CODE>openssl pkcs12 -export -inkey intermediateAppsCA/rfcuser.key.pem -in intermediateAppsCA/rfcuser.crt.pem -certfile AnotherRootCA/anotherca.cert.pem -certfile intermediateAppsCA/interApps.cert.pem -out rfcuser.p12<BR /> Enter Export Password:<BR /> Verifying - Enter Export Password:<BR /> exportpassword123</CODE></PRE><BR /> As a result I got several keys and certificates, including the most important rfcuser.p12 file, which contains user's private key and certificate with the trust chain. The file is protected with <EM>exportpassword123</EM> password. In real life scenarion this file you'll receive from your certification team.<BR /> <H1 id="toc-hId--933722372">Enforcing RFC encryption on system level</H1><BR /> Ok, I know that forcing encrypted connections is not necessary for my connection to be encrypted. However, I will do it to show if the encryption works or not. Nevertheless, if you are ready to disable unsafe connections, I highly recommend making it permanent. In my case, the <EM>snc/only_encrypted_rfc</EM> parameter is sufficient, but you might consider setting a few others as well, such as <EM>snc/accept_insecure_cpic</EM>, <EM>snc/accept_insecure_gui</EM>, <EM>snc/accept_insecure_rfc</EM>, <EM>snc/only_encrypted_gui</EM>.<BR /> <BR /> I can set the parameter to 1, which enforces encryprion for non-ABAP RFC connections. Higher levels enforces encryption for ABAP and intenal connections.<BR /> <PRE><CODE>snc/only_encrypted_rfc = 1</CODE></PRE><BR /> Now the call should be rejected by the system.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ ./startrfc -h sandbox -s 00 -u rfcuser -p secure123 -c 001 -t 3 -i<BR /> Error: Unencrypted communication is rejected by this system</CODE></PRE><BR /> It is no longer possible to establish an unencrypted connection.<BR /> <H1 id="toc-hId--360495794">SAP Cryptographic Library installation</H1><BR /> To enable RFC connection encryption, it is necessary to install a cryptographic library. On SAP systems it is included along with the kernel, while here it must be installed separately. I go to the SAP Marketplace to see what the latest version is and download it. In addition, I need to get the <EM>SAPCAR</EM> program to decompress the archive. So in the end I choose 2 files and save them in a new <EM>cryptolib</EM> folder.<BR /> <PRE><CODE>SAPCRYPTOLIBP_8553-20011697.SAR<BR /> SAPCAR_1200-70007716.EXE</CODE></PRE><BR /> It's time to unpack the library:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/cryptolib$ <STRONG>./SAPCAR_1200-70007716.EXE -xf SAPCRYPTOLIBP_8553-20011697.SAR</STRONG><BR /> SAPCAR: processing archive SAPCRYPTOLIBP_8553-20011697.SAR (version 2.01)<BR /> SAPCAR: 6 file(s) extracted</CODE></PRE><BR /> SAPCAR and the archive can be removed after extraction. Let's also start <EM>sapgenpse</EM> component to check if everything is fine.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/cryptolib$ ./sapgenpse | tail -10<BR /> Versions: SAPGENPSE 8.5.53 (Sep 22 2023)<BR /> CommonCryptoLib 8.5.53 (Sep 22 2023) [AES-NI,CLMUL,SSE3,SSSE3]<BR /> Build change list: 248172<BR /> <BR /> USER="rfcuser"<BR /> <BR /> Environment variable $SECUDIR is not defined!<BR /> Fallback selection of SECUDIR through HOME:<BR /> "/home/rfcuser/sec"</CODE></PRE><BR /> It would be good to set <EM>SECUDIR</EM> variable explicitly and add cryptolib folder to <EM>LD_LIBRARY_PATH </EM>variable. Let's edit .<EM>profile</EM> of the user.<BR /> <PRE><CODE>rfcuser@sandboxn100:~$ cat .profile<BR /> export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/nwrfcsdk/lib:~/secudir<BR /> export SECUDIR=/home/rfcuser/sec</CODE></PRE><BR /> <H1 id="toc-hId--557009299">Client PSE preparation</H1><BR /> In the previous sections, I generated an SSL certificate for the <EM>RFCUSER</EM>. It was saved in the file <EM>rfcuser.p12</EM>. Even if you don't generate the certificates yourself, you will probably get a ready one from the certification authority in this format. In the SAP world we rather operate on PSE repositories, so with the help of <EM>sapgenpse</EM> I will convert PKCS#12 to PSE. I will perform all operations in the rfcuser user <EM>sec</EM> folder.<BR /> <BR /> I prepared files, including certification authorities' certificates:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>ls -l</STRONG><BR /> total 24<BR /> -rw-r--r-- 1 rfcuser rfcuser 2033 Nov 30 18:28 anotherca.cert.pem<BR /> -rw-r--r-- 1 rfcuser rfcuser 1911 Nov 30 18:29 interApps.cert.pem<BR /> -rw------- 1 rfcuser rfcuser 5875 Nov 30 18:28 rfcuser.p12</CODE></PRE><BR /> Let's import the p12 file into new repository and protect it with <EM>MyVerySecretPIN_1</EM> secret PIN.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse import_p12 -x MyVerySecretPIN_1 -p SAPSNCS.pse -r anotherca.cert.pem -r interApps.cert.pem rfcuser.p12</STRONG><BR /> Please enter PKCS#12 encryption password: *****************<BR /> Found key 'INDEX=0,SIG=YES,ENC=YES,MD5-FINGERPRINT=60A1 B7F2 4F30 C198 9457 D2C3 5FA4 7F8E,KEYID=57F11B35BBC963B83B3B65F2666726003D11A46F'<BR /> PSE "/home/rfcuser/sec/SAPSNCS.pse" was written</CODE></PRE><BR /> The PIN we can encrypt in <EM>cred_v2</EM> file, which is kind of passwords repository. Later this can be used by tools to access the PSE file. I also update file permissions to more strict.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse seclogin -x MyVerySecretPIN_1 -p SAPSNCS.pse</STRONG><BR /> running seclogin with USER="rfcuser"<BR /> Added SSO-credentials for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> rfcuser@sandboxn100:~/sec$ <STRONG>chmod go-rwx cred_v2</STRONG></CODE></PRE><BR /> Finally I have below files with PSE and cred_v2.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ ls -l<BR /> total 28<BR /> -rw-r--r-- 1 rfcuser rfcuser 2033 Nov 30 18:28 anotherca.cert.pem<BR /> -rw------- 1 rfcuser rfcuser 114 Nov 30 18:37 cred_v2<BR /> -rw-r--r-- 1 rfcuser rfcuser 1911 Nov 30 18:29 interApps.cert.pem<BR /> -rw------- 1 rfcuser rfcuser 5875 Nov 30 18:28 rfcuser.p12<BR /> -rw------- 1 rfcuser rfcuser 5111 Nov 30 18:36 SAPSNCS.pse</CODE></PRE><BR /> Let's check what was saved in the PSE. I can see main certificate, signing CA and validity dates.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse get_my_name -p SAPSNCS.pse</STRONG><BR /> SSO for USER "rfcuser"<BR /> with PSE file "/home/rfcuser/sec/SAPSNCS.pse"<BR /> <BR /> Subject : CN=RFCUSER, O=AnotherCompany, SP=kuj-pom, C=PL<BR /> Issuer : CN=Intermediate Apps CA, OU=Apps, O=AnotherCompany, SP=kuj-pom, C=PL<BR /> Serialno : 72:7B:01:77:64:B6:60:0B:31:D7:6C:60:66:0A:B2:7E:AB:FD:77:B1<BR /> KeyInfo : RSA, 4096-bit<BR /> Validity - NotBefore: Thu Nov 30 17:54:25 2023 (231130165425Z)<BR /> NotAfter : Fri Nov 29 17:54:25 2024 (241129165425Z)<BR /> KeyUsage : none<BR /> ExtKeyUsage : ClientAuthentication<BR /> SubjectAltName : none</CODE></PRE><BR /> I can also confirm, that the trust list of the PSE is empty.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -p SAPSNCS.pse -l</STRONG><BR /> maintain_pk for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> PKList is empty.<BR /> <BR /> Empty trusted list.</CODE></PRE><BR /> <H1 id="toc-hId--753522804">SAP user update</H1><BR /> The next step is to prepare the <EM>RFCUSER</EM> user for SSO authentication. To do this, I update the <EM>SNC name</EM> field in the <EM>SNC</EM> tab in the <EM>SU01</EM> transaction. At the same time, I can disable the option of logging in with a password.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/rfc-user-snc-sso.png" /></P><BR /> <BR /> <H1 id="toc-hId--950036309">sapnwrfc.ini</H1><BR /> The <EM>sapnwrfc.ini</EM> file allows to configure connection parameters for RFC calls made with the SDK library. You can define parameters there, such as the details of the system you are connecting to, the method of authentication, or encryption. Of course, you can specify a username and password there, but I will be configuring a certificate-based SSO. So I create the <EM>sapnwrfc.ini</EM> file in the same directory as the <EM>startrfc</EM> program:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>cat sapnwrfc.ini</STRONG><BR /> DEST=a4htest<BR /> SNC_LIB=/home/rfcuser/cryptolib/libsapcrypto.so<BR /> SNC_MYNAME=p:CN=RFCUSER, O=AnotherCompany, SP=kuj-pom, C=PL<BR /> SNC_PARTNERNAME=p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany, C=PL<BR /> SNC_QOP=9</CODE></PRE><BR /> For readability, the file contains a minimum set of parameters. <EM>DEST</EM> defines the name of the connection, which must be referred to by the program making the connection. <EM>SNC_LIB</EM> defines which cryptographic library to use. <EM>SNC_MYNAME</EM> specifies the SNC name of the client. <EM>SNC_PARTNERNAME</EM> gives the SNC name of the SAP server to which we are connecting. <EM>SNC_QOP</EM> defines the scope of the SNC, where <EM>9</EM> defines the maximum available security level.<BR /> <BR /> I can return to <EM>startrfc</EM> program and update required parameters. The most important one is <EM>-D</EM>, which defines connection name, consistent with <EM>sapnwrfc.ini</EM> definition.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ ./startrfc -h sandbox -s 00 -D a4htest -i</CODE></PRE><BR /> You might notice that the parameters responsible for the username, password and client number have been removed. They are not required if the SNC string is unique, that is, only one user on one client in a given system has this specific <EM>SNC name</EM> assigned to it.<BR /> <BR /> The connection name is essential when you are securing a application that you are not the author of. The most important thing is to find in the documentation or configuration options how to determine this parameter or how to define it. Once you know this you will most likely be able to enable secure connection and encryption, even if the documentation from the vendor does not mention anything about such feature.<BR /> <H1 id="toc-hId--1146549814">Trust relationship</H1><BR /> Ok, let's start the program to see what else is missing:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -D a4htest -i</STRONG><BR /> [Thr 139683030722496] Thu Nov 30 18:50:59:304 2023<BR /> [Thr 139683030722496] *** ERROR =&gt; SncPEstablishContext() failed for target='p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany, C=PL' [/bas/753_R 3638]<BR /> Error:<BR /> LOCATION CPIC (TCP/IP) with Unicode<BR /> ERROR GSS-API(maj): Miscellaneous failure<BR /> GSS-API(min): A2210223:<STRONG>Server does not trust my certificate<BR /> path</STRONG><BR /> target="p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany,<BR /> C=PL"<BR /> TIME Thu Nov 30 18:50:59 2023<BR /> RELEASE 753<BR /> COMPONENT SNC (Secure Network Communication)<BR /> VERSION 6<BR /> RC -4<BR /> MODULE /bas/753_REL/src/krn/snc/sncxxall.c<BR /> LINE 3604<BR /> DETAIL SncPEstablishContext<BR /> SYSTEM CALL gss_i</CODE></PRE><BR /> The error message is clear - SAP server does not trust my certificate chain. What does it mean?<BR /> <BR /> The situation is as follows - the client approaches the server with a certificate, which perhaps even matches the SNC name of some user in the system. But after all, such certificate can be issued by anyone and any subject can be defined. Therefore, it is very important that the certificate is known and accepted by the server. This can be a trust relationship defined directly - by adding this particular certificate to the list. However, it can also be defined at a higher level - by trusting the certification authority.<BR /> <BR /> It is the administrator's decision, or more often security policies, at which level we establish the trust relationship. It is very convenient to add a specific CA to the trusted list and this is often the right way to go. However, be aware that this also has consequences. The organisation that issues the certificates receives the authority to authenticate users on our system.<BR /> <BR /> When we are unable to trust the certificate authority, we are required to add the leaf certificate to the list. This usually brings with it quite an inconvenience - the need to renew each certificate as it approaches its expiration date. This requires coordination with the client and, with a larger number of certificates, can be very inconvenient, especially as end certificates usually have an expiry date of one year.<BR /> <BR /> As I have full control over my certificate authorities, so I add Another Root CA to my trusted list in transaction <EM>STRUST</EM>.<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/smalltrustedliststrust.png" /><BR /> <BR /> Let's retry the connection.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -D a4htest -i</STRONG><BR /> [Thr 139834091542464] Thu Nov 30 18:58:31:277 2023<BR /> [Thr 139834091542464] *** ERROR =&gt; SncPEstablishContext() failed for target='p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany, C=PL' [/bas/753_R 3638]<BR /> Error:<BR /> LOCATION CPIC (TCP/IP) with Unicode<BR /> ERROR GSS-API(maj): Miscellaneous failure<BR /> GSS-API(min): A2200223:<STRONG>Peer certificate path not trusted</STRONG><BR /> target="p:CN=sandbox.mydomain.internal, OU=IT, O=MyCompany,<BR /> C=PL"<BR /> TIME Thu Nov 30 18:58:31 2023<BR /> RELEASE 753<BR /> COMPONENT SNC (Secure Network Communication)<BR /> VERSION 6<BR /> RC -4<BR /> MODULE /bas/753_REL/src/krn/snc/sncxxall.c<BR /> LINE 3604<BR /> DETAIL SncPEstablishContext<BR /> SYSTEM CALL gss_init_sec_context</CODE></PRE><BR /> There is still an error, but different one. This is also related to trust, but in opposite direction. Now client doesn't trust server. I need to add SAP system certificate or better it's CA to the client's trusted list. Let's go to <EM>SECUDIR</EM> and add it to <EM>PSE</EM>.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -a ca.cert.pem</STRONG><BR /> Please enter PSE PIN/Passphrase: *****************<BR /> maintain_pk for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> ----------------------------------------------------------------------------<BR /> Subject : OU=Security, O=MyCompany, SP=kuj-pom, C=PL<BR /> <BR /> PKList updated (1 entries total, 1 newly added)<BR /> <BR /> rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -a interServers.cert.pem</STRONG><BR /> Please enter PSE PIN/Passphrase: *****************<BR /> maintain_pk for PSE "/home/rfcuser/sec/SAPSNCS.pse"<BR /> ----------------------------------------------------------------------------<BR /> Subject : OU=Servers, O=MyCompany, SP=kuj-pom, C=PL<BR /> <BR /> PKList updated (2 entries total, 1 newly added)</CODE></PRE><BR /> I have to know PSE password to modify it.<BR /> <BR /> You can always your trusted list with below command:<BR /> <PRE><CODE>rfcuser@sandboxn100:~/sec$ <STRONG>../cryptolib/sapgenpse maintain_pk -l</STRONG></CODE></PRE><BR /> Now I can test the connection once more.<BR /> <PRE><CODE>rfcuser@sandboxn100:~/nwrfcsdk/bin$ <STRONG>./startrfc -h sandbox -s 00 -D a4htest -i</STRONG><BR /> SAP System ID: A4H<BR /> SAP System Number: 00<BR /> Partner Host: vhcala4hci<BR /> Own Host: sandboxn100<BR /> Partner System Release: 754<BR /> Partner Kernel Release: 777<BR /> Own Release: 753<BR /> Partner Codepage: 4103<BR /> Own Codepage: 4103<BR /> User: RFCUSER<BR /> Client: 001<BR /> Language: E</CODE></PRE><BR /> Success. Connection is possible with SSL based authentication. Encryption is obviously enabled.<BR /> <H1 id="toc-hId--1343063319">Firewall</H1><BR /> When we consider how to secure RFC connections, it is impossible to ignore the question of the firewall. It is obvious that also at the network level, we should only allow traffic from addresses that are allowed to communicate with our server. One question to ask is which ports are needed. There are two ports that are used by the Gateway, which is responsible for RFC communication - 33&lt;NN&gt;/tcp and 48&lt;NN&gt;/tcp. NN is instance number, in my case 00. 3300/tcp is used for unencrypted communication, while 4800/tcp is the secure gateway, where communication is encrypted. In my case, after configuring a secure connection, only 4800/tcp is needed.<BR /> <BR /> However, there is one more port to be considered. It is opened by the message server, which is part of the ASCS instance, that in my case is number 01. So I would also consider opening port 3601/tcp on the firewall to allow load balancing using login groups.<BR /> <H1 id="toc-hId--1539576824">UCON</H1><BR /> The final option I wanted to recommend to make RFC connections more secure is Unified Connectivity (UCON). This is a mechanism that provides the ability to define a list of allowed remote function modules. This is related to the idea of reducing the attack surface. It is clear that systems only use a very small proportion of functional modules. As the software may contain security vulnerabilities and somewhere in the system someone may have set too broad permissions, it is worth implementing protection at a higher level. UCON introduces an extra layer of protection - even before the user's permissions are checked, it is verified whether the call is on the allowed list. However, UCON is a rather broad topic for a separate article.<BR /> <H1 id="toc-hId--1736090329">Conclusion</H1><BR /> RFC connections from external non-ABAP programmes can be secured on very many levels. Security should be a priority these days and unencrypted connections forbidden by any security policy. Although we often have less control over external programs, as you can see, quite a lot can be done in this area too.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp; 2023-12-07T09:18:50+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/handling-rfc-in-sap-build-process-automation/ba-p/13580244 Handling RFC in SAP Build - Process Automation 2023-12-28T12:34:38+01:00 Metehan https://community.sap.com/t5/user/viewprofilepage/user-id/172809 <H2 id="toc-hId-964758439"><STRONG>Introduction</STRONG></H2><BR /> Hello,<BR /> <BR /> I will be showing you How to handle RFC in SAP Build - Process Automation .<BR /> <H2 id="toc-hId-768244934"><STRONG>Scenario</STRONG></H2><BR /> We will be using a RFC to get data that we need in our automation.<BR /> <H3 id="toc-hId-700814148"><STRONG>Prerequisites:</STRONG></H3><BR /> <OL><BR /> <LI>Basic Knowledge about RFC</LI><BR /> <LI>Basic knowledge about SAP Build</LI><BR /> <LI>Basic knowledge about SAP Process Automation.</LI><BR /> </OL><BR /> <H3 id="toc-hId-504300643"><STRONG>Step-by-Step Procedure:</STRONG></H3><BR /> <OL><BR /> <LI>Creating the RFC .</LI><BR /> <LI>Creating the Process Automation project.</LI><BR /> <LI>Consuming RFC in our project</LI><BR /> </OL><BR /> <H3 id="toc-hId-307787138"><STRONG>STEP 1 : Creating RFC</STRONG></H3><BR /> Firstly we need to create our RFC according to our needs. Go to <EM><STRONG>' SE37 '&nbsp;</STRONG></EM> transaction and create your RFC. Do not forget to select Remote-Enabled Module processing type.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/1-67.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 1 - RFC Attributes</P><BR /> In my case, what I needed was the mail addresses of customer numbers I already had. So created my RFC to get mail addresses using company codes and customer numbers. You should set your parameters according to your needs.<BR /> You can see my parameters below.<BR /> <P style="text-align: center;overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/2-37.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 2 - Import Parameters</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/3-27.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 3 - Tables Parameters</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/4-27.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 4 - T_CUSTOMER Components</P><BR /> In my coding part I am finding mail addresses using the customer numbers and company code provided in <EM><STRONG>T_CUSTOMER</STRONG></EM> and filling <STRONG><EM>' MAIL '&nbsp;</EM></STRONG> component according to <STRONG><EM>' IV_ CHECK '</EM></STRONG> import parameter.<BR /> <H3 id="toc-hId-111273633"><STRONG>STEP 2 : Creating Process Automation Project</STRONG></H3><BR /> Now we are going to create our project.<BR /> <BR /> Go to SAP Build cockpit and click create.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/5-17.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 5 - SAP Build Create Project</P><BR /> After that click ' Build an Automated Process ' and ' Task Automation ' . Give your project a name and configure your agent and we are all set.<BR /> <H3 id="toc-hId--85239872"><STRONG>STEP 3 : Consuming RFC in Project</STRONG></H3><BR /> Firstly we need to add <EM><STRONG>BAPI SDK</STRONG></EM> to our project. To do that go to settings and then <EM><STRONG>Dependencies</STRONG></EM> section. After that click <STRONG><EM>Add Dependency</EM></STRONG> and search for <EM><STRONG>BAPI SDK</STRONG></EM>.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/6-13.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 6 - Add Dependency</P><BR /> Now we need to create our <STRONG><EM>Data Types</EM></STRONG> based on our RFC parameters. The important part here is that Data Types must be created as structures, for my case I will be creating two Data Types , one for Import Parameters of my RFC and one for Tables Parameters.<BR /> <BR /> Go to your <STRONG><EM>Project Content</EM></STRONG> and click <EM><STRONG>Create</STRONG></EM> then click <EM><STRONG>Data Type</STRONG></EM>. After that give it a proper name and lets set the Data Type.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/7-15.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 7 - Creating Data Types</P><BR /> Create your Data Types based on your RFC parameters. Here are my Data Types<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/8-14.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 8 - Data Types</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">Now we can call our RFC from our project. Lets start building our project. You can see the general overview of project, I will be explaining each step.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/9-7.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 9 - Overview of Project</P><BR /> Firstly we need to establish our connection to SAP server where RFC exist. For that we are using <EM><STRONG>Set SAP Connection (Basic)</STRONG></EM> activity and filling it as needed.<BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: SAPRegular, 'Helvetica Neue', Arial, sans-serif;overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/10-10.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 10 - Set SAP Connection (Basic)</P><BR /> To be sure whether we were able to connect to SAP system or not we are using <EM><STRONG>Is SAP Connection Alive</STRONG></EM> activity.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/11-10.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 11 - Is SAP Connection Alive</P><BR /> <P style="overflow: hidden;margin-bottom: 0px">For next step we are creating our variable using the Data Types that we created.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/12-9.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 12 - Creating the RFC Import Variable</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/13-8.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 13 - Creating the RFC Tables Variable</P><BR /> Now that we created our variables , we are going to fill these variables. Firstly we are checking if the SAP Connection is alive or not after that we are filling our variables as we need.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/14-6.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 14 - Filling Variables</P><BR /> Now we can execute our RFC and get the desired data. To call our RFC we are using <EM><STRONG>Execute BAPI</STRONG></EM> activity. And to reach our desired data we are using <EM><STRONG>output parameter of Execute BAPI</STRONG></EM> in a <EM><STRONG>Custom Script</STRONG></EM> activity as you can see below.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/15-6.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 15 - Execute RFC</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/12/16-5.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 16 - Desired Data From RFC</P><BR /> Here is our mail addresses corresponding to customer numbers and company codes.<BR /> <H2 id="toc-hId--410836096"><STRONG>Conclusion</STRONG></H2><BR /> If you read the blog well congratulations ! You learned How to create a new project in SAP Build, How to create custom Data Types in a SAP Process Automation, How to consume a RFC in SAP Process Automation and much more.<BR /> <BR /> <EM>If this blog is a help to you please like and share <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span>&nbsp;</EM><BR /> <DIV><BR /> <DIV><BR /> <BR /> <EM>Also Please do not hesitate to ask any further questions and feel free to share your feedback on the content.</EM><BR /> <BR /> <EM><STRONG>Thank you!</STRONG></EM><BR /> <PRE><CODE><STRONG>- Metehan Dülger </STRONG></CODE></PRE><BR /> </DIV><BR /> <DIV></DIV><BR /> </DIV> 2023-12-28T12:34:38+01:00 https://community.sap.com/t5/application-development-and-automation-blog-posts/created-a-program-to-fetch-customer-details-from-as400-system-to-sap-s4hana/ba-p/13619246 Created a program to fetch customer details from AS400 system to SAP S4HANA via RFC FM 2024-02-28T13:31:37.538000+01:00 harsh_raj1 https://community.sap.com/t5/user/viewprofilepage/user-id/152044 <P>Creating a program to fetch customer details from an AS400 system to SAP S/4HANA via RFC (Remote Function Call) involves several steps. Below is a simplified example to illustrate the process. Note that you need the appropriate authorization and system connectivity settings for RFC communication.</P><H3 id="toc-hId-1116273783">Using Transaction SM59:</H3><OL><LI><P><STRONG>Log in to SAP GUI:</STRONG></P><UL><LI>Log in to the SAP GUI using the appropriate credentials.</LI></UL></LI><LI><P><STRONG>Open Transaction SM59:</STRONG></P><UL><LI>Enter transaction code SM59 in the command field and press Enter.</LI></UL></LI><LI><P><STRONG>Choose RFC Connection:</STRONG></P><UL><LI>In the SM59 screen, navigate to the "RFC Connections" folder in the left-hand tree structure.</LI></UL></LI><LI><P><STRONG>Create RFC Destination:</STRONG></P><UL><LI>Right-click on the "RFC Connections" folder, choose "Create," and select the appropriate connection type (for example, "TCP/IP Connections" for remote systems).</LI></UL></LI><LI><P><STRONG>Enter Connection Details:</STRONG></P><UL><LI>Fill in the required details for the RFC destination, including the connection type, the target system's IP address or hostname, and the system number.</LI></UL></LI><LI><P><STRONG>Configure Logon &amp; Security:</STRONG></P><UL><LI>Configure the logon and security settings. This might include specifying the user credentials that will be used for communication.</LI></UL></LI><LI><P><STRONG>Additional Parameters:</STRONG></P><UL><LI>Depending on your scenario, you may need to configure additional parameters, such as language, code page, or other connection-specific settings.</LI></UL></LI><LI><P><STRONG>Test Connection:</STRONG></P><UL><LI>Before saving the RFC destination, you can use the "Connection Test" button to check if the connection to the target system is successful.</LI></UL></LI><LI><P><STRONG>Save the RFC Destination:</STRONG></P><UL><LI>Once the connection test is successful, save the RFC destination.</LI></UL></LI><LI><P><STRONG>Activate and register&nbsp;the RFC Destination:</STRONG></P><UL><LI>After saving the destination, you may need to activate and register it. The activation ensures that the settings take effect.</LI></UL></LI><LI><P><STRONG>Use the RFC Destination in ABAP Programs:</STRONG></P><UL><LI>You can use the created RFC destination in ABAP programs by calling the remote function modules defined in the target system.<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_0-1708951919820.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71246i814B426F5B50173C/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_0-1708951919820.png" alt="harsh_raj1_0-1708951919820.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_1-1708952589257.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71264i55F1949E37D8B5EF/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_1-1708952589257.png" alt="harsh_raj1_1-1708952589257.png" /></span><P><STRONG>Create RFC-Enabled Function Module in SAP S/4HANA:</STRONG></P><UL><LI>Create an RFC-enabled function module in SAP S/4HANA that will call the RFC function module in the AS400 system. This function module should take any necessary parameters, call the RFC function module in the AS400 system, and return the customer details. <span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_4-1708949394238.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71182i6D2B21728C58811B/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_4-1708949394238.png" alt="harsh_raj1_4-1708949394238.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_5-1708949436424.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71183i4D1D8A442E2B49C7/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_5-1708949436424.png" alt="harsh_raj1_5-1708949436424.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_6-1708949471493.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71184i6DE369551A825D78/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_6-1708949471493.png" alt="harsh_raj1_6-1708949471493.png" /></span><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_7-1708949530552.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71186iD7FE2FCC6E8AF505/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_7-1708949530552.png" alt="harsh_raj1_7-1708949530552.png" /></span></LI></UL></LI></UL></LI></OL><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>FUNCTION zhr_fm_knb1_fico. *"---------------------------------------------------------------------- *"*"Local Interface: *" IMPORTING *" VALUE(IM_KUNNR) TYPE ZHR_TTY_KNB1 OPTIONAL *" EXPORTING *" VALUE(GT_KNB2) TYPE ZHR_TT_KNB1 *" VALUE(EP_MSG) TYPE STRING *" TABLES *" GT_KNB1 STRUCTURE KNB1 *"---------------------------------------------------------------------- IF im_kunnr IS NOT INITIAL. SELECT FROM knb1 FIELDS kunnr, bukrs, erdat, ernam WHERE kunnr in _KUNNR INTO CORRESPONDING FIELDS OF TABLE _knb2 . IF gt_knb1 IS INITIAL. ep_msg = 'No record found'. ENDIF. ENDIF. ENDFUNCTION.</code></pre><P>&nbsp;</P><P>&nbsp;<SPAN>Creating a report program in SAP S/4HANA using the ABAP Editor (SE38) involves defining a report using the Report&nbsp;</SPAN><SPAN>statement, fetching data from the database, and displaying the results. Below is a simple example of a report program that retrieves and displays data from knb1 table.</SPAN></P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>*&amp;---------------------------------------------------------------------* *&amp; Report ZHR_RP_FM *&amp;---------------------------------------------------------------------* *&amp; *&amp;---------------------------------------------------------------------* REPORT ZHR_RP_FM. DATA: lv_kunnr TYPE kunnr. * SELECT-OPTIONS: s_kunnr FOR lv_kunnr. DATA: lt_range type RANGE OF kunnr. lt_range = VALUE #( sign = 'I' option = 'BT' ( low = s_kunnr-low ) ( high = s_kunnr-high ) ). DATA: lt_knb1 TYPE TABLE OF knb1, gt_knb1 TYPE TABLE of knb1, * gs_knb1 TYPE knb1, lv_msg TYPE string. START-OF-SELECTION. * CALL FUNCTION 'ZHR_FM_KNB1_FICO' DESTINATION 'zhr_a4hana_to_s4hana' EXPORTING im_kunnr = lt_range IMPORTING GT_KNB2 = gt_knb1 "gs_knb1 EP_MSG = lv_msg tables gt_knb1 = lt_knb1 . IF sy-subrc &lt;&gt; 0. * Implement suitable error handling here ENDIF. IF gt_knb1[] is NOT INITIAL. cl_demo_output=&gt;display( gt_knb1 ). ENDIF.</code></pre><P>&nbsp;</P><P>output:</P><P>give the input and click on execute button.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_0-1708950301655.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71237i5C48F50B46E7A013/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_0-1708950301655.png" alt="harsh_raj1_0-1708950301655.png" /></span></P><P>provide your user-id for s4hana along with password and click on enter.</P><P>it will display the desired output.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_2-1708952759789.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71268i24414975FFD71A86/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_2-1708952759789.png" alt="harsh_raj1_2-1708952759789.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh_raj1_2-1708950014638.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/71236iB4474CFD26FF86B1/image-size/large?v=v2&amp;px=999" role="button" title="harsh_raj1_2-1708950014638.png" alt="harsh_raj1_2-1708950014638.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P> 2024-02-28T13:31:37.538000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/create-trusted-rfc-with-specific-technical-user/ba-p/13694181 Create trusted RFC with specific technical user 2024-05-08T17:46:41.940000+02:00 Austin_Nguyen https://community.sap.com/t5/user/viewprofilepage/user-id/42832 <P><SPAN>As the SAP Basis administrator, we know that we can establish the trusted RFC between ABAP systems in which we can connect to the target system with our current user without providing the credentials like in screenshot below.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_0-1715101552453.png" style="width: 514px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106978i86E93B9327375E79/image-dimensions/514x135?v=v2" width="514" height="135" role="button" title="austinnguyen_0-1715101552453.png" alt="austinnguyen_0-1715101552453.png" /></span></P><P><SPAN>But what if we want to use a specific technical user and still want to benefit from trusted RFC? Actually, we can do it with the same method and I will show you how in this blog post.</SPAN></P><P><SPAN>First of all, since we need to create the trusted RFC, we need to establish the trusted relationship between systems through transaction code SMT1. In the scope of this blog, I’ll assume that we need to define the trust between system AA and BB.</SPAN></P><P>1.&nbsp;<SPAN>Go to SMT1 Tcode on AA, and click the “Create” button to start the process.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_1-1715101603516.png" style="width: 605px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106979i9C45744ADD2F458A/image-dimensions/605x223?v=v2" width="605" height="223" role="button" title="austinnguyen_1-1715101603516.png" alt="austinnguyen_1-1715101603516.png" /></span></P><P>2.&nbsp;<SPAN>Click “Continue”.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_2-1715101638658.png" style="width: 607px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106980i307F7AC367BA5FAB/image-dimensions/607x492?v=v2" width="607" height="492" role="button" title="austinnguyen_2-1715101638658.png" alt="austinnguyen_2-1715101638658.png" /></span></P><P>3.&nbsp;<SPAN>On the next screen, we need to provide the information about the target server and login information. It'll create a new RFC on the target server called "TRUSTING@&lt;SID&gt;xxxxxxxx".</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_3-1715101658069.png" style="width: 612px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106981i0BD4AF7A26B6AF6E/image-dimensions/612x491?v=v2" width="612" height="491" role="button" title="austinnguyen_3-1715101658069.png" alt="austinnguyen_3-1715101658069.png" /></span></P><P>4.&nbsp;<SPAN>On the following screens, just click on “Continue” and “Finish” on the final screen.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_4-1715101674781.png" style="width: 611px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106982i1538606103989217/image-dimensions/611x489?v=v2" width="611" height="489" role="button" title="austinnguyen_4-1715101674781.png" alt="austinnguyen_4-1715101674781.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_5-1715101685108.png" style="width: 614px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106983iC1E281E0154BCD03/image-dimensions/614x494?v=v2" width="614" height="494" role="button" title="austinnguyen_5-1715101685108.png" alt="austinnguyen_5-1715101685108.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_6-1715101700657.png" style="width: 615px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106984i5F579CE9E71E7F78/image-dimensions/615x492?v=v2" width="615" height="492" role="button" title="austinnguyen_6-1715101700657.png" alt="austinnguyen_6-1715101700657.png" /></span></P><P>5.&nbsp;<SPAN>Now, it’s finished on the first system AA and you need to do the same steps on the second system BB.</SPAN></P><P><SPAN>Next, we need to make sure that the technical user on the source system has enough authorizations to allow the trusted call from the source system.</SPAN></P><P><SPAN>For that purpose, the user role needs to have the authorization object S_RFCACL. Below is the description of its field.</SPAN></P><UL><LI><SPAN>ACTVT: always 16. It’s the only value we can specify.</SPAN></LI><LI><SPAN>RFC_CLIENT: In this field, we can specify which client we allow to make the trusted connection. For example: the AA system has 3 clients 001, 002, and 003, but if we want to grant the trusted connection from client 002 only, then we need to specify here the value 002. The connection from clients 001 and 003 will be rejected.</SPAN></LI><LI><SPAN>RFC_EQUSER: This is the important field for making trusted RFCs with another user. In this case, we want to connect with a specific technical user, therefore we set it to value “</SPAN><STRONG>N</STRONG><SPAN>”.</SPAN></LI><LI><SPAN>RFC_INFO: the installation number of the calling system. We can set it to ‘*’, then the role can be used by multiple source systems, or you can specify here the list of installation numbers that allow you to create a trusted connection.</SPAN></LI><LI><SPAN>RFC_SYSID: SID of the calling system.</SPAN></LI><LI><SPAN>RFC_TCODE: Calling transaction code.</SPAN></LI><LI><SPAN>RFC_USER: ID of the calling user.</SPAN><P><SPAN>After finishing the role creation, please make sure that the role will be assigned to the technical user on the called system.</SPAN></P><P><SPAN>We have come to the final step. For details on creating the RFC in SM59, please refer to the SAP help documentation. In this blog, I’ll focus only on trusted RFC settings.</SPAN></P><P><SPAN>After specifying the target hostname and SID, go to the Logon &amp; Security tab and set the Trust Relationship to “Yes”.</SPAN></P><P><SPAN>Now, instead of setting the checkbox at “Current User”, we will leave it blank and give the information about the technical user from the called system. Of course, the password is no longer necessary because we’re creating a trusted connection.</SPAN></P></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_7-1715101766516.png" style="width: 624px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106985iE4C7DD2969ED5D7A/image-dimensions/624x496?v=v2" width="624" height="496" role="button" title="austinnguyen_7-1715101766516.png" alt="austinnguyen_7-1715101766516.png" /></span></P><P><SPAN>Save the connection and execute “Authorization Check”.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_8-1715101778797.png" style="width: 628px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106986i70A61F858AB0F4C4/image-dimensions/628x295?v=v2" width="628" height="295" role="button" title="austinnguyen_8-1715101778797.png" alt="austinnguyen_8-1715101778797.png" /></span></P><P><SPAN>At this point, if you log in to the called system and go to TCode SM59. Then you will see the connection from the calling system but from that technical user, not ours.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="austinnguyen_9-1715101791303.png" style="width: 633px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/106987i77B6B1D9077CE4C3/image-dimensions/633x45?v=v2" width="633" height="45" role="button" title="austinnguyen_9-1715101791303.png" alt="austinnguyen_9-1715101791303.png" /></span></P><P><SPAN>I hope that blog will find you well. If you have any questions or concerns so far, feel free to contact me.</SPAN></P> 2024-05-08T17:46:41.940000+02:00 https://community.sap.com/t5/technology-blog-posts-by-members/creating-rfc-function-module-its-web-services-in-sap-amp-amp-testing-using/ba-p/13705811 Creating RFC function module , Its Web services in SAP &amp; Testing using SOAPUI. 2024-05-18T14:25:20.820000+02:00 Srikanta_Kumar_Gouda1221 https://community.sap.com/t5/user/viewprofilepage/user-id/1454912 <P><SPAN>Introduction:</SPAN><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>By leveraging RFC, organizations can enable robust data exchange and process integration across different SAP and non-SAP systems.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>However, creating RFCs is only half the battle. To harness their full potential, these RFCs often need to be exposed as web services, providing a standardized way for external applications to interact with SAP functionalities. This is where the power of web services comes into play, bridging diverse systems and enabling seamless, real-time data transactions.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>But how can you ensure that these web services are functioning correctly? This is where testing tools like SOAPUI become invaluable. SOAPUI allows developers and testers to validate the performance, security, and reliability of web services before they go live, ensuring smooth and error-free operations.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>In this blog post, we will dive deep into the process of creating RFCs in SAP, transforming them into web services, and rigorously testing them using SOAPUI. Whether you are a seasoned SAP professional or a newcomer looking to enhance your integration skills, this guide will provide you with the insights and tools needed to master SAP web services and ensure their optimal performance.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN><SPAN>STEPS</SPAN><SPAN>&nbsp;</SPAN></P><OL><LI><SPAN>Create a function group in SE80.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_0-1716031664471.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112562iD638F3AAE878CD23/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_0-1716031664471.png" alt="Pramod_Hiremath_0-1716031664471.png" /></span></P><P><SPAN>&nbsp;2.</SPAN><SPAN>Provide the package name &amp; click on SAVE.</SPAN></P><P><SPAN><BR /></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_1-1716031664473.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112563iBD55B6EA0AF9E544/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_1-1716031664473.png" alt="Pramod_Hiremath_1-1716031664473.png" /></span></P><P><SPAN>3.Activate the FUNCTION GROUP.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_2-1716031664474.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112564iB28F559364D71A89/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_2-1716031664474.png" alt="Pramod_Hiremath_2-1716031664474.png" /></span></P><P><SPAN>4.Execute the T-code SE37 &amp; Create a FUNCTION MODULE.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_3-1716031664475.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112565iAF8D0F4ED85BC1B7/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_3-1716031664475.png" alt="Pramod_Hiremath_3-1716031664475.png" /></span><SPAN>&nbsp;</SPAN></P><OL><LI><SPAN>&nbsp;Give the Function group name, short description &amp; click on SAVE.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_4-1716031664475.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112566i7036C771D5ABEEE8/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_4-1716031664475.png" alt="Pramod_Hiremath_4-1716031664475.png" /></span><BR /><BR /></P><OL><LI><SPAN>Click on the Radio button REMOTE ENABLED MODULE&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_5-1716031664478.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112567i81261880A103BC86/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_5-1716031664478.png" alt="Pramod_Hiremath_5-1716031664478.png" /></span><BR /><BR /></P><OL><LI><SPAN>Take some importing parameters in order to receive the values as per the requirement.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_6-1716031664480.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112568i7B16ACD13B8F1A95/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_6-1716031664480.png" alt="Pramod_Hiremath_6-1716031664480.png" /></span><BR /><BR /></P><OL><LI><SPAN>Take one exporting parameter to return the message if the value is not found.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_7-1716031664481.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112569iDDE80058C2D14347/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_7-1716031664481.png" alt="Pramod_Hiremath_7-1716031664481.png" /></span></P><P>&nbsp;</P><OL><LI><SPAN>Take internal tables in order to store multiple data. Here, Gt_mara is referring to mara structure having some fields like MATNR, ERSDA &amp;&nbsp; Gt_marc&nbsp; is referring to marc structure having some fields like MATNR, PLIFZ.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_8-1716031664482.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112570iD42547F561C0AAD8/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_8-1716031664482.png" alt="Pramod_Hiremath_8-1716031664482.png" /></span><SPAN>&nbsp;</SPAN></P><OL><LI><SPAN>You can write your own logic to test the RFC FM, whether it returns some value or not.</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_9-1716031664484.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112573i40F0B5CC218A0AF7/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_9-1716031664484.png" alt="Pramod_Hiremath_9-1716031664484.png" /></span><BR /><BR /></P><OL><LI><SPAN>Now, check the result by providing input values from MARA &amp; MARC</SPAN><SPAN>&nbsp;</SPAN></LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_10-1716031664486.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112572i34C69D2CE2FF1E3A/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_10-1716031664486.png" alt="Pramod_Hiremath_10-1716031664486.png" /></span></P><P><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_11-1716031664487.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112571i40C2CC3B48547B21/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_11-1716031664487.png" alt="Pramod_Hiremath_11-1716031664487.png" /></span></P><P><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_12-1716031664488.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112574i82761DB3C9E4079D/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_12-1716031664488.png" alt="Pramod_Hiremath_12-1716031664488.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_13-1716031664488.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112575iDA4F18091E50256F/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_13-1716031664488.png" alt="Pramod_Hiremath_13-1716031664488.png" /></span><BR /><BR /></P><P><SPAN>12.now, create its webservice from function module.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_14-1716031664489.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112576i67644DB0E8A93E38/image-size/medium?v=v2&amp;px=400" role="button" title="Pramod_Hiremath_14-1716031664489.png" alt="Pramod_Hiremath_14-1716031664489.png" /></span></P><P><SPAN>&nbsp;13.&nbsp;</SPAN><SPAN>Provide the service definition &amp; description.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_15-1716031664491.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112577iD0EA7280ED21B50B/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_15-1716031664491.png" alt="Pramod_Hiremath_15-1716031664491.png" /></span></P><P><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_16-1716031664492.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112579i3C46BE860105C830/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_16-1716031664492.png" alt="Pramod_Hiremath_16-1716031664492.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_17-1716031664493.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112578i6607BCBCF2908DE4/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_17-1716031664493.png" alt="Pramod_Hiremath_17-1716031664493.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_18-1716031664495.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112581i608CF6A41B4A0A8E/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_18-1716031664495.png" alt="Pramod_Hiremath_18-1716031664495.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_19-1716031664497.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112582i245C728FF3E6B3DD/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_19-1716031664497.png" alt="Pramod_Hiremath_19-1716031664497.png" /></span></P><P><SPAN>14. Below we can see the service definition properties. And activate it.</SPAN><SPAN>&nbsp;</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_20-1716031664498.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112580i839A176BA3A5DABC/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_20-1716031664498.png" alt="Pramod_Hiremath_20-1716031664498.png" /></span>&nbsp;</P><OL><LI><SPAN>&nbsp;Execute the T-code <STRONG>SOAMANAGER </STRONG>in S4HANA.&nbsp;</SPAN><SPAN>&nbsp;</SPAN>&nbsp;</LI></OL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_21-1716031664499.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112583iEDEEF6EF87D5914C/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_21-1716031664499.png" alt="Pramod_Hiremath_21-1716031664499.png" /></span></P><P><STRONG>Click on to the Webpages.&nbsp;</STRONG></P><P><SPAN>16.Provide your Hana-user id &amp; Password.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_22-1716031664502.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112585iDDC8BE7641AB593A/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_22-1716031664502.png" alt="Pramod_Hiremath_22-1716031664502.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;17.</SPAN><SPAN>Click on web service configuration.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_23-1716031664505.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112584iF29D6EA2216C82DE/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_23-1716031664505.png" alt="Pramod_Hiremath_23-1716031664505.png" /></span><BR /><BR />18.<SPAN>Choose the object type as Object Name and pass the correct service definition name. If the service definition exists, then we can be able to see ‘entry found’ otherwise not found.</SPAN><SPAN>&nbsp;</SPAN></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_24-1716031664506.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112586i16E8C2B2E7952E9C/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_24-1716031664506.png" alt="Pramod_Hiremath_24-1716031664506.png" /></span></P><P><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_25-1716031664508.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112587iD2F38F79D2B3E088/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_25-1716031664508.png" alt="Pramod_Hiremath_25-1716031664508.png" /></span><SPAN>&nbsp;</SPAN></P><P><SPAN>19.Now, Click on Internal Name ---&gt;Click on Create service.&nbsp;</SPAN><SPAN>&nbsp;<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_27-1716032478137.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112590i6B6DB09116DDE415/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_27-1716032478137.png" alt="Pramod_Hiremath_27-1716032478137.png" /></span></P><P><SPAN><BR />20.</SPAN><SPAN>Fill up the details like service &amp; binding name, Provide security, SOAP protocol &amp; Operation settings.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_28-1716032502249.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112591i752C912208A120D8/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_28-1716032502249.png" alt="Pramod_Hiremath_28-1716032502249.png" /></span><BR /><BR /></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_29-1716032536645.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112592iAB440AADD8CDA294/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_29-1716032536645.png" alt="Pramod_Hiremath_29-1716032536645.png" /></span></P><P><SPAN>&nbsp;21.</SPAN><SPAN>Fill up the provide security</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_30-1716032620620.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112593i52D908BDC6346BE4/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_30-1716032620620.png" alt="Pramod_Hiremath_30-1716032620620.png" /></span><BR /><BR /><BR /></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_32-1716032702986.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112595iC44973C817D32099/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_32-1716032702986.png" alt="Pramod_Hiremath_32-1716032702986.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_31-1716032696645.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112594iE8167A16F9389CF3/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_31-1716032696645.png" alt="Pramod_Hiremath_31-1716032696645.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;22.</SPAN><SPAN>No need to fill out SOAP protocol details so, click on next. In operation settings click on finish.</SPAN> <SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_33-1716032753539.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112596i0D378675B5651262/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_33-1716032753539.png" alt="Pramod_Hiremath_33-1716032753539.png" /></span><BR /><BR /><BR />23.<SPAN>Then Choose the service &amp; activated--&gt; below interface will open--&gt; click on save</SPAN><SPAN>&nbsp;.</SPAN></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_34-1716032793811.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112597i4B264943E46CA5FB/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_34-1716032793811.png" alt="Pramod_Hiremath_34-1716032793811.png" /></span><BR /><BR />24.<SPAN>Select the service &amp; click on republish</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_35-1716032885383.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112598iCDA796F1B5991D18/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_35-1716032885383.png" alt="Pramod_Hiremath_35-1716032885383.png" /></span><SPAN>&nbsp;</SPAN></P><P>&nbsp;</P><OL><LI><SPAN>Click on save </SPAN><SPAN><SPAN>&nbsp;<BR /></SPAN></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_36-1716032914591.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112599i40E9CA8605E5B16D/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_36-1716032914591.png" alt="Pramod_Hiremath_36-1716032914591.png" /></span><P>&nbsp;</P><SPAN>26. Don’t provide any details, click on OK.</SPAN><SPAN><SPAN>&nbsp;<BR /></SPAN></SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_37-1716032951122.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112600iCFDE81FD95197A5E/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_37-1716032951122.png" alt="Pramod_Hiremath_37-1716032951122.png" /></span><BR /><BR />27.<SPAN>&nbsp;Click on the below Execute button under the WSDL generation.&nbsp;</SPAN><SPAN>&nbsp;</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_38-1716033030943.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112601i9A9A89219DEDC25B/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_38-1716033030943.png" alt="Pramod_Hiremath_38-1716033030943.png" /></span><BR /><BR /></LI></OL><P><SPAN>&nbsp;28.</SPAN><SPAN>&nbsp;Press CTRL+S and save the file in WSDL format.</SPAN><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_39-1716033091308.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112602iF99DD903E5B8E0E8/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_39-1716033091308.png" alt="Pramod_Hiremath_39-1716033091308.png" /></span></P><P><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_40-1716033197666.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112603i8D658740DA7B88A5/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_40-1716033197666.png" alt="Pramod_Hiremath_40-1716033197666.png" /></span></P><P><SPAN><BR />29. Now, we are ready to test the service in SOAPUI. S</SPAN><SPAN>o, let's download the SOAPUI.</SPAN></P><P><SPAN>Notes:</SPAN></P><P><SPAN>&nbsp;how to Download the SOAPUI software &amp; implement it.</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>&nbsp;Go to </SPAN><SPAN>SOAPUI.ORG</SPAN><SPAN> website and download SOAPUI open source.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_41-1716033275587.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112604i45FE680A66735639/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_41-1716033275587.png" alt="Pramod_Hiremath_41-1716033275587.png" /></span></P><P><SPAN>&nbsp;<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_42-1716033403570.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112605i093E3007CFF1922A/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_42-1716033403570.png" alt="Pramod_Hiremath_42-1716033403570.png" /></span></P><P>&nbsp;</P><UL><LI><SPAN>Below is the interface of how the SoapUI looks like. can start doing the API testcases.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI><LI><SPAN>Click on soap--&gt;new soap project--&gt; give a project name --&gt;choose the WSDL which we have downloaded --&gt;ok</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_43-1716033423652.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112606iB0B21F7359A9DA2F/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_43-1716033423652.png" alt="Pramod_Hiremath_43-1716033423652.png" /></span></P><P><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_44-1716033479047.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112607iCB2DF1765F89F895/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_44-1716033479047.png" alt="Pramod_Hiremath_44-1716033479047.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_45-1716033511356.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112608i0DE68C8E76A71269/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_45-1716033511356.png" alt="Pramod_Hiremath_45-1716033511356.png" /></span></P><P>&nbsp;</P><UL><LI><SPAN>Click upon request1 then we can see the details in XML file.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_46-1716033530496.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112609iE653D1A0DDF801D1/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_46-1716033530496.png" alt="Pramod_Hiremath_46-1716033530496.png" /></span></P><P>&nbsp;</P><UL><LI><SPAN>To access the data, provide the authorization. Click on add new authorization.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_47-1716033585666.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112610i481517D65F1AD7A2/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_47-1716033585666.png" alt="Pramod_Hiremath_47-1716033585666.png" /></span></P><P>&nbsp;</P><UL><LI><SPAN>Finally, we can see the result as shown below. For success the status code will be 200.</SPAN><SPAN>&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pramod_Hiremath_26-1716031664511.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112588i8CAC50293601FB3D/image-size/large?v=v2&amp;px=999" role="button" title="Pramod_Hiremath_26-1716031664511.png" alt="Pramod_Hiremath_26-1716031664511.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;</SPAN></P> 2024-05-18T14:25:20.820000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/technical-user-propagation-from-jco-towards-on-premises/ba-p/13704538 Technical User Propagation from JCo towards On-Premises 2024-05-22T15:06:16.024000+02:00 simon_luser https://community.sap.com/t5/user/viewprofilepage/user-id/771659 <P data-unlink="true">This blog lays out how to use a technical user instead of basic authentication from <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/invoke-abap-function-modules-in-on-premise-abap-systems?locale=en-US" target="_self" rel="noopener noreferrer">JCo based on the SAP Java Buildpack in CF</A> towards on-premises.</P><P data-unlink="true">&nbsp;</P><H1 id="toc-hId-885667874">Background</H1><P data-unlink="true">JCo retrieves an access token representing the technical user which is then be sent to the Connectivity service. This is similar to principal propagation, but in this case, a technical user is propagated instead of a business user. The retrieval of the access token performs the OAuth 2.0 client credentials flow, according to the token service configurations in the destination. Currently for JCo the token service generation supports basic authentication only. The token service is called from the Internet, not from the Cloud Connector.</P><P data-unlink="true">&nbsp;</P><H1 id="toc-hId-689154369">Configuration</H1><P>Generally speaking, the setup as described in the <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/invoke-abap-function-modules-in-on-premise-abap-systems?locale=en-US" target="_self" rel="noopener noreferrer">documentation</A> stays the same, only the destination configuration in the Destination Service needs to be adjusted.</P><P>In the UI select the authentication type&nbsp;<EM><STRONG>TechnicalUserPropagation</STRONG></EM>. You now need to enter three values for:</P><UL><LI><STRONG>jco.client.tech_user_id</STRONG> - the technical user name (client ID) which is forwarded towards on-premises and used for token retrieval</LI><LI><STRONG>jco.client.tech_user_secret</STRONG> - the secret for <EM>jco.client.tech_user_id</EM> used for token retrieval</LI><LI><STRONG>jco.client.tech_user_service_url</STRONG> - the URL of the token service<SPAN>, against which the token exchange is performed</SPAN></LI></UL><H2 id="toc-hId-621723583"><SPAN>Example</SPAN></H2><P><SPAN>We are going to use the token of the XSUAA service instance here. We specified for the instance in the configuration JSON the <STRONG>xsappname</STRONG> as <EM>jco-technicalProp</EM>.</SPAN></P><P><SPAN>After the application binding we can retrieve the relevant parameters from the CF environment variables VCAP_SERVICES:</SPAN></P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-json"><code>"clientid": "sb-jco-technicalProp!t77058" "clientsecret": "TMsePptYQLSRf6qUWWt+l1D0rUQ=" "url": "https://cf.authentication.hana.ondemand.com"</code></pre><P>&nbsp;</P><P>&nbsp;</P><P><SPAN>Entering it in the Destination Service:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Properties" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/113368iDC4EDC134023C774/image-size/medium?v=v2&amp;px=400" role="button" title="simon_luser_0-1716286606143.png" alt="simon_luser_0-1716286606143.png" /></span></P><P><SPAN>The token will now be forwarded to the Cloud Connector. Assuming all necessary basic <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/configuring-principal-propagation?locale=en-US" target="_self" rel="noopener noreferrer">steps</A> for principal propagation are configured, we can <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/configure-subject-patterns-for-principal-propagation?locale=en-US" target="_self" rel="noopener noreferrer">configure a pattern</A> to extract its name for the short-lived certificate:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Pattern" style="width: 259px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/112153iE8E7F78470E681B7/image-dimensions/259x107?v=v2" width="259" height="107" role="button" title="simon_luser_1-1715949812665.png" alt="simon_luser_1-1715949812665.png" /></span></P><P><SPAN>The ABAP backend needs to <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/cloud-connector-configure-principal-propagation-for-rfc?locale=en-US&amp;version=Cloud#2.-map-short-lived-certificates-to-users" target="_self" rel="noopener noreferrer">maintain a user mapping</A> for this technical user, in this case mapping it to the ABAP user <EM>SKYWALKER</EM>:</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Mapping" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/113369iC19FACFAECE438B4/image-size/medium?v=v2&amp;px=400" role="button" title="simon_luser_1-1716286913724.png" alt="simon_luser_1-1716286913724.png" /></span></P><P><SPAN>That's it!</SPAN></P> 2024-05-22T15:06:16.024000+02:00 https://community.sap.com/t5/technology-blog-posts-by-members/how-to-call-restful-apis-from-sap-abap-a-step-by-step-guide/ba-p/13926663 How to Call RESTful APIs from SAP ABAP: A Step-by-Step Guide 2024-11-08T09:53:20.246000+01:00 Vrushali_15 https://community.sap.com/t5/user/viewprofilepage/user-id/171052 <P><FONT size="4" color="#0000FF">Introduction to RESTful APIs:</FONT></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RESTful APIs provide a simple way to interact with web services, making them a powerful tool for SAP developers. In this blog post, we'll explore how to call RESTful APIs from SAP ABAP, covering everything from setup to practical examples.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Some basic terms while calling API.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>API:</STRONG> API stands for Application Programming Interface. Are set of rules that allow programs to communicate with each other.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>REST:</STRONG> REST stands for Representational State Transfer. It is an architectural style for providing standards between systems on web which makes easier for systems to communicate with each other.&nbsp;<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>REST API:</STRONG> The API’s which follows REST methodologies for the communication. In this, communication is done in form of <STRONG>Request</STRONG> and <STRONG>Response.</STRONG> Response is nothing but a request from server to the client.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Request</STRONG> is made up of mainly 4 things<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1) <STRONG>Endpoint:</STRONG> It is the URL you request for, it contains the target host and the prefix path.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2) <STRONG>Methods</STRONG>: Rest API generally uses four methods to communicate with server.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Methods&nbsp;</STRONG><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a) <STRONG>Get</STRONG>&nbsp;- This method is used to get data from the server<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b) <STRONG>Post -</STRONG> This method is used to create new data entry on the server<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c) <STRONG>Put</STRONG>&nbsp;- This method is used to update any data on the server. It will replace the entire resources with provided data.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d) <STRONG>Patch -</STRONG> This method is also used to update any data on the server like put only difference is it allow you to update specific fields or properties that you want to change.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e) <STRONG>Delete</STRONG>&nbsp;- This method is used to delete data from the server</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3)<STRONG>&nbsp;Headers:</STRONG> Headers are used to provide authentication and provide information of the body content.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4) <STRONG>The Body:</STRONG> The data you want to send to the server is sent through the request body. This data is sent either in JSON format or XML format.</P><P>&nbsp;</P><P><FONT size="4" color="#0000FF">Prerequisites:</FONT><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Ensure you have the necessary authorizations to call HTTP requests. You might need the following:<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>HTTP Service:</STRONG> Ensure that the HTTP service is enabled in your SAP system. This can be checked and configured in transaction SICF (SAP Internet Communication Framework).<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>Authorization:</STRONG> Make sure your user has the necessary permissions to make HTTP calls and manage the HTTP destination.</P><P>&nbsp;</P><P><FONT size="4" color="#0000FF">Setting Up the Environment:&nbsp;</FONT></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; After executing SM59 below screen will be visible.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vrushali_15_0-1730626070106.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/186237i070FC6092BF9CD0E/image-size/medium?v=v2&amp;px=400" role="button" title="Vrushali_15_0-1730626070106.png" alt="Vrushali_15_0-1730626070106.png" /></span></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1) <STRONG>ABAP Connections:</STRONG> Type 3 means Connection to ABAP System.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2) <STRONG>HTTP connection to External Server:</STRONG> Type G means we will connect SAP system with Non - SAP system or third party system.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3) <STRONG>HTTP connection to ABAP System</STRONG>: Type H means HTTP Connection to ABAP System<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4) <STRONG>Internal Connections:</STRONG> Type I means connection to Application Server with Same Database.&nbsp;<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5) <STRONG>Logical Connections:</STRONG> Type L means Reference Entry (Refers to Other Destination)<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6) <STRONG>TCP/IP Connections:</STRONG> Type T means start External Program Using TCP/IP.&nbsp;<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7) <STRONG>Connection via ABAP Driver:</STRONG> Type X means RFC Using Special ABAP Driver Routines.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vrushali_15_0-1730626357787.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/186238iC40998D8D89A9D27/image-size/medium?v=v2&amp;px=400" role="button" title="Vrushali_15_0-1730626357787.png" alt="Vrushali_15_0-1730626357787.png" /></span></P><P>&nbsp;</P><P><FONT size="4" color="#0000FF"><STRONG>Connecting SAP with Non - SAP System</STRONG></FONT><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; So, we are going to connect SAP with Non - SAP system. For that we need to create RFC connection of type G i.e. HTTP Connections to External Server. Below is the procedure for creating connection.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1) Firstly, we need to click on create button as below.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vrushali_15_1-1730626608779.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/186239iA628EFA885BB4BAF/image-size/medium?v=v2&amp;px=400" role="button" title="Vrushali_15_1-1730626608779.png" alt="Vrushali_15_1-1730626608779.png" /></span></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2) After clicking on create button below screen will be visible. We need to enter target host i.e. URL of third party.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vrushali_15_2-1730626745796.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/186240i607E57FFBD70B797/image-size/medium?v=v2&amp;px=400" role="button" title="Vrushali_15_2-1730626745796.png" alt="Vrushali_15_2-1730626745796.png" /></span></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ For HTTP connection.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- Give Service number (Port number) : 80<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- Select SSL as inactive in ‘Logon &amp; Security’.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ For HTTPS Connection.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- Give Service number (Port number): 443.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- Configure proxy settings with help of BASIS team.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- Configure SSL certificate in t-code ‘STRUST’ with help of BASIS team.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;- Select SSL as active and select ‘ANONYM SSL’ as shown in picture below.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(Difference between HTTP &amp; HTTPS is HTTPS provides a secure, encrypted connection that helps protect your data and privacy, whereas HTTP does not.).&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3) Then click on ‘Connection Test’ button on upper left corner in order to test the connection we are trying to establish. If following screen appears we can assume that connection is established successfully.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vrushali_15_0-1730627068100.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/186242i88BD4C23CBB7A4F2/image-size/medium?v=v2&amp;px=400" role="button" title="Vrushali_15_0-1730627068100.png" alt="Vrushali_15_0-1730627068100.png" /></span></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4)&nbsp;And after that we need to upload that SSL certificates if necessary using Transaction Code ‘STRUST’ under ‘SSL client SSL Clent (Standard) ‘as maintain below.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Vrushali_15_1-1730627128306.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/186243i9BD03F35DC4055E3/image-size/medium?v=v2&amp;px=400" role="button" title="Vrushali_15_1-1730627128306.png" alt="Vrushali_15_1-1730627128306.png" /></span></P><P>&nbsp;</P><P><FONT size="4" color="#0000FF">Making HTTP Requests from ABAP:</FONT></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; There is special class in SAP called ‘CL_REST_HTTP_CLIENT’ which can be used to communicate with REST API. In this class there are 2 methods for calling API.</P><P><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<FONT size="4"><STRONG>1) 1st Method is ‘CREATE_BY_DESTINATION’</STRONG></FONT></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>Step 1:</STRONG> First we have to create HTTP object for the URL destination we want to access.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <STRONG>Code:</STRONG></P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code> DATA: LO_HTTP_CLIENT TYPE REF TO IF_HTTP_CLIENT. CL_HTTP_CLIENT=&gt;CREATE_BY_DESTINATION ( EXPORTING DESTINATION = 'E-Invoicing' "Name of the RFC destination IMPORTING CLIENT = LO_HTTP_CLIENT " HTTP Client object EXCEPTIONS ARGUMENT_NOT_FOUND = 1 DESTINATION_NOT_FOUND = 2 DESTINATION_NO_AUTHORITY = 3 PLUGIN_NOT_ACTIVE = 4 INTERNAL_ERROR = 5 OTHERS = 6 ).</code></pre><P>&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>Step 2:</STRONG> Set the method and version you want to use for the communication, here we have used POST method. And HTTP version as 1.0.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <STRONG>Code:</STRONG></P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>lo_http_client-&gt;request-&gt;set_method(if_http_request=&gt;co_request_method_post ). lo_http_client-&gt;request-&gt;set_version(if_http_request=&gt;co_protocol_version_1_1 ). </code></pre><P>&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁<STRONG> Step3:</STRONG> Set request parameters, if any.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code> lv_url = /test.com/ewb/enc/v1.03/authentication'. CALL METHOD cl_http_utility=&gt;set_request_uri EXPORTING request = lo_http_client-&gt;request uri = lv_url.</code></pre><P>&nbsp;</P><P><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;⦁ <STRONG>Step4:</STRONG> Set the request header if any.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code> CALL METHOD lo_http_client-&gt;request-&gt;set_header_field EXPORTING IV_NAME = 'Authorization' IV_VALUE = ‘l7xxba7aa16e968646b993426bsd6734h:201806034242’.</code></pre><P>&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step5:</STRONG> Set the type of data you want to send to request body. Below are some examples.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ If you are sending JSON pass ‘application/json’.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ If you are sending XML data pass ‘application/xml’ or ‘text/xml’.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ IF you are sending multipart data pass ‘multipart/form-data’.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG> (Here I am sending JSON file)</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code> LO_HTTP_CLIENT-&gt;REQUEST-&gt;SET_CONTENT_TYPE( 'application/json' ).</code></pre><P>&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step6:</STRONG> Pass actual data to the request. In following example lv_string contains JSON string which is we are going to pass to request.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:&nbsp;</STRONG></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code> DATA : lv_string type string. LO_HTTP_CLIENT-&gt;REQUEST-&gt;SET_CDATA( LV_STRING ).</code></pre><P>&nbsp;</P><P><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step7:</STRONG> Send request to the API and receive the response.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code>call method lo_http_client-&gt;send “sending request to API exceptions http_communication_failure = 1 http_invalid_state = 2. call method lo_http_client-&gt;receive “receiving response from API Exceptions http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3.</code></pre><P>&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step8:</STRONG> Read HTTP return code and the response. Example if 200 is a success return code, 500 for internal server error, 400 for bad request. In the below example we get the response from the API in the string ‘response’.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-abap"><code> DATA: http_status type string, Reason type string, Response type string. call method lo_http_client-&gt;response-&gt;get_status importing code = http_status reason = reason. response = lo_http_client-&gt;response-&gt;get_cdata( ).</code></pre><P>&nbsp;</P><P><FONT size="4"><STRONG>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2) 2nd method is 'CREATE_BY_URL'</STRONG></FONT><BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step 1:</STRONG> First we have to create HTTP object for the URL destination we want to access.<BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG></P><pre class="lia-code-sample language-abap"><code> DATA: lo_http_client TYPE REF TO cl_http_client, lv_url TYPE string, lv_response TYPE string, lv_status TYPE i. lv_url = 'https://api.example.com/data'. cl_http_client=&gt;create_by_url( EXPORTING url = lv_url IMPORTING client = lo_http_client EXCEPTIONS argument_not_found = 1 plugin_not_active = 2 internal_error = 3 OTHERS = 4 ).</code></pre><P><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step 2:</STRONG> Set the method and version you want to use for the communication, here we have used POST method. And HTTP version as 1.0.<BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG><BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</P><pre class="lia-code-sample language-abap"><code>lo_http_client-&gt;request-&gt;set_method( 'POST' ). lo_http_client-&gt;request-&gt;SET_VERSION(if_http_request=&gt;co_protocol_version_1_1 ).</code></pre><P><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step 3:</STRONG> Set the request header if any necessary.<BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<STRONG>Code:</STRONG><BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</P><pre class="lia-code-sample language-abap"><code>lt_http = VALUE #( ( name = 'accesstoken' value = ‘12344566743’ ) ( name = 'apiaccesskey' value = ’ER452DD234’) ( name = 'Content-Type' value = 'application/json' ) ). lo_http_client-&gt;request-&gt;set_header_fields( fields = lt_http ). lo_http_client-&gt;request-&gt;set_content_type( 'application/json' ).</code></pre><P><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step 4:</STRONG> Pass actual data to the request. In following example lv_string contains JSON string which is we are going to pass to request.<BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <STRONG>Code:</STRONG></P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><pre class="lia-code-sample language-abap"><code> lo_http_client-&gt;request-&gt;set_data( lv_string).</code></pre><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step 5:</STRONG> Send request to the API and receive the response.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <STRONG>Code:</STRONG><BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><pre class="lia-code-sample language-abap"><code>lo_http_client-&gt;send( “Sending the request EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 ). lo_http_client-&gt;receive( “Receiving the response EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3 ).</code></pre><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ⦁ <STRONG>Step 6:</STRONG> Read HTTP return code and the response. Example if 200 is a success return code, 500 for internal server error, 400 for bad request. In the below example we get the response from the API in the string ‘response’.</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <STRONG>Code:</STRONG><BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><pre class="lia-code-sample language-abap"><code> Data: lv_response TYPE string, lv_http_return_code TYPE I . lv_response = lo_http_client-&gt;response-&gt;get_cdata( ). lo_http_client-&gt;response-&gt;get_status(IMPORTING code = lv_http_return_code ).</code></pre><P><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <STRONG>&nbsp;<FONT color="#0000FF">Conclusion</FONT></STRONG><FONT color="#0000FF">:</FONT><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Connecting RFCs in SAP is a powerful way to integrate different systems and enable seamless communication across your SAP landscape. By following above steps you can set up your RFC.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Feel free to reach out if you have any questions or run into issues during your implementation.</P><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P> 2024-11-08T09:53:20.246000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/how-to-save-a-lot-of-time-with-the-abap-connector-transaction-aco-proxy/ba-p/13943675 How to Save a Lot of Time With the ABAP Connector (Transaction ACO_PROXY) 2024-12-31T22:42:01.243000+01:00 thomas_weiss https://community.sap.com/t5/user/viewprofilepage/user-id/181896 <H4 id="toc-hId-1333839708"><STRONG>Introduction and Overview</STRONG></H4><P>Are you tired of creating large numbers of data types in your client-system when you call a remote enabled function module (RFM) by RFC and the data types of its parameters do not exist on the client? Let transaction ACO_PROXY do it for you. In a fraction of the time you need to create all these data types yourself, this tool, also called ABAP connector (ACo) and available as of ABAP 7.40, generates:</P><UL><LI><STRONG>All</STRONG> <STRONG>data types</STRONG> of an RFM’s parameters as well as <STRONG>the parameters</STRONG> <STRONG>themselves </STRONG>&nbsp;and</LI><LI>A <STRONG>static global proxy</STRONG> class with a method that encapsulates the call of this RFM by RFC. &nbsp;</LI></UL><TABLE border="1" width="100%"><TBODY><TR><TD width="100%"><STRONG>Note</STRONG>: You can also generate <STRONG>one ACo proxy class for</STRONG> <STRONG>RFC calls of several RFMs</STRONG>, if calling each of them with a different method of the same proxy class makes sense from a design perspective. Since, in principle, it is irrelevant to the explanations in this weblog whether a proxy class covers calls to one or many RFMs and in order to keep things simple, I explain the concepts and features of transaction ACO_PROXY using the case of generating a proxy that calls one RFM.</TD></TR></TBODY></TABLE><P>Reading this weblog,</P><UL><LI>You get an idea of how much time you save with ACO_PROXY by looking at a real-world example with a BAPI that uses hundreds of elementary data types in its interface. (“BAPI” is short for Business Application Programming Interface. You find some more explanation of this concept in the next section below.)</LI></UL><TABLE border="1" width="100%"><TBODY><TR><TD width="100%"><STRONG>Note</STRONG>: Transaction ACO_PROXY performs a recursive analysis of all complex data types used in the relevant RFM’s interface down to the elementary ones and recreates all of them in the client system. Since this tool creates global data types, you can use them not only in your caller program, but in any program in your client system.</TD></TR></TBODY></TABLE><UL><LI>Get to know the few simple steps it takes to have this transaction create these data types and a proxy class.</LI><LI>You learn about some more options this tool offers such as instantiating the proxy class via a constructor vs. using a factory class or directly calling the proxy class vs. calling it via an interface etc. &nbsp;(again, all additional entities such as a factory class or an interface will be generated by this tool).</LI><LI>You get to know why you always should choose RFC’s fast serialization for new scenarios when calling RFMs via ACo proxy.</LI><LI>You see how little code is needed in the client program to call an RFM via an ACo proxy class.</LI><LI>You understand why, in most cases, you are better off with a static proxy – generated by transaction ACO_PROXY – than with a dynamic proxy – generated by an ACo API – and also why in one specific case the dynamic ACo proxy is a better choice.&nbsp;</LI></UL><TABLE border="1" width="100%"><TBODY><TR><TD width="100%"><P><STRONG>Note</STRONG>: Two other use cases of transaction ACO_PROXY are just mentioned in this introduction, because the first one needs little explanation, and the second one is treated in great detail in a weblog of an SAP colleague:</P><OL><LI>Obviously, an ACo proxy class supports you in writing completely object-oriented code, when you need to call an RFM via RFC, because the call itself is hidden in the generated proxy class.</LI><LI>In the weblog <A href="https://community.sap.com/t5/technology-blogs-by-sap/how-to-generate-a-wrapper-for-function-modules-bapis-in-tier-2/ba-p/13692790" target="_blank"><STRONG>How to generate a wrapper for function modules (BAPIs) in tier 2</STRONG></A> my SAP colleague Andre Fischer discusses how you profit from an ACo proxy when you want to call a local RFM which is not C1-released &nbsp;in a program compliant with Clean Core guidelines: In this case, transaction ACO_PROXY generates a C1-released factory class, a C1-released interface for the ACo proxy class, and the proxy class itself. For all further details<SPAN> you are recommended to read my SAP colleague’s weblog. </SPAN></LI></OL></TD></TR></TBODY></TABLE><H4 id="toc-hId-1137326203"><STRONG>How ACo Saves You a Lot of Time – a Real-World Example</STRONG></H4><P>Let us now consider a real-world example of using transaction ACO_PROXY: &nbsp;</P><P>Imagine yourself writing a client program which calls the BAPI BAPI_BUPA_ADDRESS_CHANGE &nbsp;by RFC to change the address of a business partner. Its interface has 8 importing and 38 table parameters, which all have complex data types, and neither the BAPI nor any of its data types exist in your client system.<BR /><BR /></P><TABLE border="1" width="100%"><TBODY><TR><TD width="100%"><STRONG>Note</STRONG>: “BAPI” is an Acronym for “Business Application Programming Interface”. From a technical perspective a BAPI is an RFM for which SAP guarantees a stable interface. From a business perspective BAPIs are interfaces to business objects, which are implemented as function modules.</TD></TR></TBODY></TABLE><P>If we break all these complex data types down into their components, we get almost 800 elementary data types, which you all have to recreate in the client system – and on top of them also the 46 complex data types. Assuming that you are a fast developer, let us estimate that, on average, in ABAP Dictionary (transaction SE11), it takes you one minute to define an elementary data type and another 20 seconds per component to define a complex data type. Based on this very optimistic estimate, you need about 17 hours for this job.</P><P>When you are facing such a repetitive task, transaction ACO_PROXY is a game changer: Just enter the name of the relevant RFM and of a suitable destination as well as some other values in the tool. This is all it takes to make this transaction generate all the almost 800 elementary and 46 complex data types used in this BAPI’s parameters and a proxy class for an RFC call to the BAPI BAPI_BUPA_ADDRESS_CHANGE.</P><P>With transaction “ACO_PROXY”, it takes a few minutes to generate the many hundred data types in our example, compared to about 17 hours you need for this task without tool support. In fact, 17 hours is an optimistic estimate for such a job, actually creating all data types used in the parameters of BAPI BAPI_BUPA_ADDRESS_CHANGE might take far longer.</P><H4 id="toc-hId-940812698"><STRONG>Basic Steps to Create a Static ACo Proxy</STRONG></H4><P>Let us now dive into the details of how to use this transaction. Below, there is a screenshot of ACO_PROXY’s UI with a few numbered labels, which refer to relevant input fields to be explained in this section. You will get to know also some more details of the transaction’s UI in the section to follow.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Picture 1: Transaction ACO_PROXY and its input fields" style="width: 844px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/206225iDD8CBD1CB146B110/image-size/large?v=v2&amp;px=999" role="button" title="ACO_Proxy_smaller.png" alt="Picture 1: Transaction ACO_PROXY and its input fields" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">Picture 1: Transaction ACO_PROXY and its input fields</span></span></P><UL><LI>ACo transaction needs to know <STRONG>where to get the called RFM’s metadata (cf. label 1):</STRONG></LI><UL><LI>You select the option “<STRONG>locally</STRONG>” if the respective RFM is available on your client system.</LI><LI>In case you choose “<STRONG>by RFC</STRONG>”, you need to input a destination pointing to your target system or to another system that contains the relevant RFM.</LI><LI>If the respective metadata are to be retrieved <STRONG>via file upload</STRONG>, first get them into the relevant file. To achieve this, you also use the ACo tool’s “Get Metadata” options and, again, you choose between the two options “locally” and “by RFC”. &nbsp;Next, select “File” (<STRONG>cf. label 2</STRONG>) in the line starting with the label “Create” and then press the execute button or F8. In the popup shown next you input file name plus location and confirm.</LI></UL></UL><TABLE border="1" width="100%"><TBODY><TR><TD width="100%"><P><STRONG>Note</STRONG>: The option to get the metadata by RFC – whether you retrieve them directly from the remote system or upload them from a file that in turn has got them from the remote system - is needed if, for example, you want to generate an ACo Proxy call to an RFM that, in your landscape, is not available on any system whose release supports transaction “ACO_PROXY”.</P></TD></TR></TBODY></TABLE><UL><LI>Enter the na<STRONG>me(s) of the RFM(s)</STRONG> for which ACo should generate a proxy with the data types of the RFM’s parameters (<STRONG>cf. label 3</STRONG>). (Surely you remember that you can create a proxy class to encapsulate the connections to one or many RFM depending on what suits your design best.)</LI><LI>Enter <STRONG>name and package of your proxy class</STRONG> (<STRONG>cf. label 4</STRONG>).</LI><LI>Define whether to create a proxy class for (a) a&nbsp;<STRONG>synchronous RFC call</STRONG>, (b) an&nbsp;<STRONG>asynchronous one with or without response / result method</STRONG> or (c) a <STRONG>bgRFC call</STRONG>. (<STRONG>cf. label 5</STRONG>) While using the synchronous RFC proxy is the self-explanatory default option, options (b) and (c) need some more explanation: As for option (b), an ACo proxy for an asynchronous RFC call with response also has a result method, and you need a sync point in your client program where it waits until the asynchronous response is available and where it can process the result once it is provided. Option (c), creating an ACo proxy that encapsulates a bgRFC call, requires prior creation of a bgRFC unit, which needs to be passed to the relevant method of the ACo proxy class.</LI></UL><H4 id="toc-hId-744299193"><STRONG>More Options in Transaction “ACO_PROXY”</STRONG></H4><P>You can also choose:</P><UL><LI>Whether you prefer to create the proxy instance using a constructor or a factory class.</LI><LI>Whether you want to create an interface, in which case you have to enter its name. Selection of this option is enforced by the tool, if &nbsp;“Create Factory Class” is chosen.</LI><LI>(a) Whether you want to create a public instance method of the proxy class to encapsulate the RFC call or (b) Whether you prefer to use a private instance method to achieve this, in which case – in addition to the private method - also a public method is generated that, in turn, calls this private method. &nbsp;</LI><LI>(a) Whether you want to pass the destination name to the relevant proxy method when calling an RFM – which is the default – or (b) whether you want to pass the destination via constructor, in which case you should select the respective option. Note that, in the latter case, &nbsp;usage of interface IF_RFC_DEST is mandatory in SAP BTP ABAP Environment and SAP S/4HANA Cloud Public Edition.</LI><LI>Whether you want the called RFM(s) to throw class-based, classic or BAPI exceptions.</LI><LI>Whether you want to generate the relevant objects so that they can be used system -internally, in which case you select “C1 Release”. In this case, you should also define if you want to create only C1-released data types that do not already exist in the system. This is what the option “Do not Create Shadows of C1-released Types” is for.</LI></UL><P>Normally, you are almost done now. Just press “Execute” or F8 to generate:</P><UL><LI>A persistent proxy class.</LI><LI>An &nbsp;instance method that encapsulates the call of the respective RFM for each RFM covered by this proxy class a method and a constructor.</LI><LI>All complex and elementary data types of the relevant RFMs’ parameters.</LI><LI>(If you have made the respective choice) an interface and a factory class.</LI></UL><H4 id="toc-hId-547785688"><STRONG>Always Choose the Correct Serialization in Destinations Used in an RFC Call via ACo Proxy </STRONG></H4><P>In an SM59 destination that is used in an RFC call via an ACo proxy you should always select these options in the tab “Special Options”:</P><UL><LI>“Protocol -&gt; Serializer -&gt; <STRONG>Fast serializer</STRONG>” plus &nbsp;</LI><LI>“Interface Check for Fast Serialization -&gt; <STRONG>Destination for new scenario</STRONG>“</LI></UL><P>With any other serialization or interface check, you might run the risk of data corruption due to incorrect data offset, which might happen to a parameter with a structured data type if this data type differs between client and server system. Though the probability that this might occur is small, once it happens, it might corrupt a large part of the data in the relevant table or structure and thereby cause big harm. <STRONG>Therefore, it is important to always choose fast serialization for new scenarios in destinations used by an ACo proxy</STRONG>.</P><H4 id="toc-hId-351272183"><STRONG>The Code to Call an RFM with an ACo Proxy</STRONG></H4><P>Now, let us call an ACo proxy in a program. Suppose you have created a proxy class zcl_rfc_system_info, which calls RFM RFC_SYSTEM_INFO via RFC, which needs the destination name in the constructor, and which you want to call in the same system.</P><P>This is how you instantiate this class and pass destination SELF to the constructor:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="ACO_Code_1_60.png" style="width: 678px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/206229iDF07102B72E53806/image-size/large?v=v2&amp;px=999" role="button" title="ACO_Code_1_60.png" alt="ACO_Code_1_60.png" /></span></P><P>&nbsp;<SPAN>And this is the code to call this RFM using the proxy class instance:</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="ACO_Code_2_60.png" style="width: 667px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/206228iFD3D3DC86CFB7414/image-size/large?v=v2&amp;px=999" role="button" title="ACO_Code_2_60.png" alt="ACO_Code_2_60.png" /></span></P><P>&nbsp;<SPAN>Obviously, this code is self-explaining and does not offer any surprise for you ABAP developers.<BR /><BR /></SPAN></P><TABLE border="1" width="100%"><TBODY><TR><TD width="100%">Note: The name of the public instance method to call an RFM always is the name of the respective RFM. But there is no need to choose a proxy class name that contains the respective RFM’s name – as we do it in the example above.</TD></TR></TBODY></TABLE><H4 id="toc-hId-154758678"><STRONG>Static vs. Dynamic ACo Proxy</STRONG></H4><P>There is also the option to create a dynamic ACo proxy class, and certainly you want to know, if there are use cases, in which a dynamic proxy might be advantageous over the static proxy generated by transaction “ACO_PROXY”. So, let’s start with a short description how dynamic ACo proxy works:<BR /><BR /></P><TABLE border="1" width="100%"><TBODY><TR><TD width="100%"><STRONG>Note</STRONG>: For a code example of how to create and use a dynamic ACo proxy, look at the program SAP_ACO_EXAMPLE_DYNAMIC_PROXY – also delivered with ABAP 7.40. Developers familiar with using SAP JAVA and SAP .NET Connector will see that, in many respects, creating and using a dynamic ACo proxy class is similar to how you things work with these other two connectors.</TD></TR></TBODY></TABLE><P>Each time a program runs that uses a dynamic ACo proxy to call an RFM, this proxy is created via API based on the respective RFMs metadata. The dynamic proxy class is not persisted. For this reason, the parameters of the proxy class are always up-to-date, even after an upgrade of the server side involving changes to the respective RFM’s interface, which would require recreation of a static proxy. This, at first sight, appears to be a big advantage of the dynamic proxy over the static one. But in this case, appearances are deceiving:</P><P>If, for example, after an upgrade, the relevant RFM has additional input or output parameters, a developer has to adapt the client program’s code – be it to process additional output values or to pass values to the additional input parameters. But if developer action is required in any case – to extend the client program accordingly -, then it makes little difference whether or not the ACo proxy class also needs to be re-created as in the case of a static proxy: Compared to the effort required to adapt the client program, the additional effort needed to recreate the proxy class is negligible. Therefore, as to the case of changes to the RFM’s interface, what, at first sight, may appear to be a big advantage of the dynamic over the static proxy, in fact, carries no weight.</P><P>In contrast, the advantages of the static proxy are weighty:</P><UL><LI>Working with a static proxy is faster at runtime because it is created at design time and it can be re-used.</LI><LI>All global data types generated by the ACo transaction are statically available and therefore easy to use in a program while, in contrast, all program code using elements of the dynamic proxy must be completely dynamic, which is why using the dynamic proxy requires significant experience in dynamic programming.</LI></UL><P>Therefore, we arrive at the conclusion that, in most cases, you are better off using the static proxy. But – and this is the relevant exception -, you should choose the dynamic ACo proxy, if it is used in a completely dynamic framework. In all other cases, you should prefer the static proxy over the dynamic one.<BR /><BR /></P><TABLE border="1" width="100%"><TBODY><TR><TD width="100%"><STRONG>Note</STRONG>: As with all RFC calls and no matter which kind of ACo proxy you use, after an upgrade of the respective the server system, you should have a look into possible changes of the respective RFM’s interface and also test the relevant connections. If needed, just recreate your static ACo proxy and – as required or useful for your client-program - adapt or extend the program’s code no matter which flavor of ACo you use.</TD></TR></TBODY></TABLE><H4 id="toc-hId--41754827"><STRONG>Summary</STRONG></H4><P>After all, transaction ACO_PROXY</P><UL><LI>First and foremost, saves you a lot of time,</LI><LI>If you call an RFM on a remote system and if neither this RFM nor its parameters’ data types exist in the client system,</LI><LI>By generating a static proxy class as well as all relevant data types and parameters.</LI></UL><P>Normally, you are better off with a static than with a dynamic proxy class to be created by an ACo API. Only if the ACo proxy should be part of a fully dynamic framework, you should use dynamic ACo. In all other cases the static proxy is not only fully sufficient but even the better choice.</P><P>Just try it out and you will see: Transaction ACO_PROXY really is a big time saver.</P><P>&nbsp;</P> 2024-12-31T22:42:01.243000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/netweaver-rfc-sdk-moving-from-python-to-c/ba-p/13977082 NetWeaver RFC SDK: moving from Python to C 2025-01-06T19:19:37+01:00 LucaFalavigna https://community.sap.com/t5/user/viewprofilepage/user-id/615776 <P>As several users of the <A href="https://github.com/SAP-archive/PyRFC" target="_self" rel="nofollow noopener noreferrer">PyRFC Python bindings</A>&nbsp;&nbsp;might have noticed, <A href="https://github.com/SAP-archive/PyRFC/issues/372#issuecomment-2541490558" target="_self" rel="nofollow noopener noreferrer">SAP decided to discontinue the project</A> due to lack of internal resources and the impossibility of finding a new maintainer who might have access to NetWeaver RFC SDK source code to keep the bindings up to date, mainly due to the fact the SDK itself is not free &amp; open software like its bindings.</P><P>Needless to say this is a very sad news for me, who is an avid user of the PyRFC package, but also for the Free &amp; Open Software community who recorded another casualty due to non permissive licenses despite <A href="https://pages.community.sap.com/topics/open-source" target="_self" rel="noopener noreferrer">SAP believes in Free &amp; Open Source</A>. I hope this paradox will become clear, one day.</P><P>&nbsp;</P><H2 id="toc-hId-1078558259">Moving (back) to C/C++</H2><P>Python bindings were not just the only affected project, also <A href="https://github.com/SAP-archive/node-rfc/issues/329#issuecomment-2541486229" target="_self" rel="nofollow noopener noreferrer">Node.js</A> and other bindings were discontinued as well, leaving no other choice of moving to either C or C++ to get official support from SAP, so I decided to try to convert one of my sample PyRFC scripts into a C program to be executed either in Linux or Windows. This is the original script in Python, which queries RFC_GET_SYSTEM_INFO&nbsp;to get system details:</P><P>&nbsp;</P><pre class="lia-code-sample language-python"><code>from pyrfc import Connection from pyrfc._exception import LogonError conn_params = { 'user': '***', 'passwd': '***', 'mshost': '***', 'msserv': '***', 'r3name': '***', 'group': '***', 'client': '***', 'lang': '***' } try: conn = Connection(**conn_params) result = conn.call('RFC_GET_SYSTEM_INFO') except LogonError as e: print(e) exit(1) rfcsi = result['RFCSI_EXPORT'] print(f'RFCDEST: {rfcsi['RFCDEST']}') print(f'PFCSYSID: {rfcsi['RFCSYSID']}') print(f'RFCDBSYS: {rfcsi['RFCDBSYS']}') conn.close()</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>This is the equivalent written in C, which is significantly larger in size and much more complex to read and understand, although it's been a while since I last touched the language and it could be there are easier ways to achieve the same results:</P><P>&nbsp;</P><pre class="lia-code-sample language-c"><code>#include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; #include "sapnwrfc.h" #define NUM_PARAMS 8 int main(int argc, SAP_UC** argv){ RFC_CONNECTION_PARAMETER loginParams[NUM_PARAMS]; loginParams[0].name = cU("MSHOST"); loginParams[0].value = cU("***"); loginParams[1].name = cU("MSSERV"); loginParams[1].value = cU("***"); loginParams[2].name = cU("R3NAME"); loginParams[2].value = cU("***"); loginParams[3].name = cU("GROUP"); loginParams[3].value = cU("***"); loginParams[4].name = cU("CLIENT"); loginParams[4].value = cU("***"); loginParams[5].name = cU("USER"); loginParams[5].value = cU("***"); loginParams[6].name = cU("PASSWD"); loginParams[6].value = cU("***"); loginParams[7].name = cU("LANG"); loginParams[7].value = cU("***"); RFC_ERROR_INFO errorInfo; RFC_CONNECTION_HANDLE conn; RFC_FUNCTION_HANDLE funcHandle; RFC_FUNCTION_DESC_HANDLE funcDescHandle; RFC_STRUCTURE_HANDLE sysInfoHandle; RFC_RC rc; SAP_UC buffer[100]; conn = RfcOpenConnection(loginParams, NUM_PARAMS, &amp;errorInfo); if (errorInfo.code != RFC_OK) { printfU(cU("Connection failed: %s\n"), errorInfo.key); } funcDescHandle = RfcGetFunctionDesc(conn, cU("RFC_GET_SYSTEM_INFO"), &amp;errorInfo); if (funcDescHandle == NULL) { printfU(cU("Error getting function description: %s\n"), errorInfo.message); exit(1); } funcHandle = RfcCreateFunction(funcDescHandle, &amp;errorInfo); if (funcHandle == NULL) { printfU(cU("Error creating function: %s\n"), errorInfo.message); exit(1); } rc = RfcInvoke(conn, funcHandle, &amp;errorInfo); if (rc != RFC_OK) { printfU(cU("Error invoking function: %s\n"), errorInfo.message); exit(1); } rc = RfcGetStructure(funcHandle, cU("RFCSI_EXPORT"), &amp;sysInfoHandle, &amp;errorInfo); if (rc != RFC_OK) { printfU(cU("Error getting RFCSI_EXPORT: %s\n"), errorInfo.message); exit(1); } RfcGetString(sysInfoHandle, cU("RFCDEST"), buffer, sizeof(buffer), NULL, &amp;errorInfo); printfU(cU("RFCDEST: %s\n"), &amp;buffer); RfcGetString(sysInfoHandle, cU("RFCSYSID"), buffer, sizeof(buffer), NULL, &amp;errorInfo); printfU(cU("RFCSYSID: %s\n"), &amp;buffer); RfcGetString(sysInfoHandle, cU("RFCDBSYS"), buffer, sizeof(buffer), NULL, &amp;errorInfo); printfU(cU("RFCDBSYS: %s\n"), &amp;buffer); RfcDestroyFunction(funcHandle, &amp;errorInfo); RfcCloseConnection(conn, &amp;errorInfo); return 0; }</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>Quite surprisingly, the execution time is taking longer for the ELF binary derived from the C source rather than the interpreted Python script (0,8 seconds on average for the ELF binary against 0,7 seconds for the Python script), while normally ELF binaries are orders of magnitude faster than their equivalent in Python. Trying to analyze where the biggest performance impact is located, it seems the Unicode functions are taking a big portion of the load, which surprises me even more...</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Perf.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/208312iF85BCD75BE90D4C4/image-size/large?v=v2&amp;px=999" role="button" title="Perf.png" alt="Perf.png" /></span></P><P>&nbsp;</P><H2 id="toc-hId-882044754">Final considerations</H2><P>Converting my scripts from Python to C seems feasible, there's a learning curve to master as I need to familiarize again with C after many years of Python, but little by little I should be able to get there.</P><P>I would like to hear from you whether there are solutions for the Unicode inefficiency, some linking parameters I somehow missed perhaps?</P> 2025-01-06T19:19:37+01:00 https://community.sap.com/t5/enterprise-resource-planning-blog-posts-by-members/getting-started-with-sap-snc-for-rfc-integrations/ba-p/13983462 Getting Started with SAP SNC for RFC integrations 2025-01-12T17:20:02.514000+01:00 Martin-Pankraz https://community.sap.com/t5/user/viewprofilepage/user-id/143781 <P><SPAN>Dear community,</SPAN></P><P><SPAN>Many of you still rely heavily on the legacy SAP interface RFC. In my world that often means customers connecting their third-party services to SAP backends (AS ABAP). Securing a protocol such as SAP Remote Function Call (RFC) requires network layer protection.</SPAN></P><P><SPAN>Often Kerberos is discussed on this topic, because it allows the mapping of Windows-Known identities to SAP backend users. However, <STRONG>this post is about apps and technical connections using X.509 certs</STRONG> – not people. They complain less – and boringly but reliably behave the same way once configured properly</SPAN><span class="lia-unicode-emoji" title=":winking_face:">😉</span><SPAN> Meet <STRONG>SAP Secure Network Communications</STRONG> (SNC).</SPAN></P><P><EM><SPAN>By the way: In case you want user-based flows and focus on SAP Principal Propagation have a look at <A href="https://community.sap.com/t5/technology-blogs-by-members/principal-propagation-in-a-multi-cloud-solution-between-microsoft-azure-and/ba-p/13561150" target="_blank">this series</A> by my beloved colleague <A href="https://community.sap.com/t5/user/viewprofilepage/user-id/171519" target="_blank">Martin Raepple</A>.</SPAN></EM></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="SAP SNC integration architecture overview" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210985i9E08478E04A64031/image-size/large?v=v2&amp;px=999" role="button" title="Picture1.png" alt="SAP SNC integration architecture overview" /><span class="lia-inline-image-caption" onclick="event.preventDefault();">SAP SNC integration architecture overview</span></span></P><P>&nbsp;</P><H2 id="toc-hId-1079366398"><SPAN>Welcome to the world of <A href="https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_751_IP/e73bba71770e4c0ca5fb2a3c17e8e229/e656f466e99a11d1a5b00000e835363f.html" target="_blank" rel="noopener noreferrer">SAP Secure Network Communication</A>s (SNC) for trustworthy technical connections!</SPAN></H2><P><SPAN>In light of zero-trust efforts customers want to secure their technical connections to SAP RFCs too. In that space certificate-based authentication mechanisms are king. SNC is a prominent choice.</SPAN></P><P><SPAN>There are libraries for languages like <A href="https://support.sap.com/en/product/connectors/jco.html" target="_blank" rel="noopener noreferrer">Java</A>, <A href="https://support.sap.com/en/product/connectors/msnet.html" target="_blank" rel="noopener noreferrer">DotNet</A>, <A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">C/C++</A>, <A href="https://github.com/SAP-archive/PyRFC" target="_blank" rel="noopener nofollow noreferrer">Python</A>, and <A href="https://github.com/SAP-archive/node-rfc" target="_blank" rel="noopener nofollow noreferrer">NodeJS</A> that support SNC for RFC. Python and NodeJS were recently archived and will no longer be maintained. In case you get stuck, consider <A href="https://blogs.sap.com/2023/05/17/generate-soap-services-for-your-legacy-rfcs-to-simplify-integration-out-of-the-box/" target="_blank" rel="noopener noreferrer">generating SOAP services for your SAP RFCs</A> to uplevel the communication stack to layer 7 for use with TLS instead.</SPAN></P><P class="lia-align-center" style="text-align: center;"><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="MartinPankraz_1-1736697403542.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210981iC0A2D3111564937D/image-size/medium?v=v2&amp;px=400" role="button" title="MartinPankraz_1-1736697403542.png" alt="MartinPankraz_1-1736697403542.png" /></span></P><P class="lia-align-center" style="text-align: center;"><SPAN>Source: <A href="https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_751_IP/e73bba71770e4c0ca5fb2a3c17e8e229/3f3dacb1c27344e29f3c7b5864825eb5.html" target="_blank" rel="noopener noreferrer">SAP Help</A></SPAN></P><P><SPAN>Below I will show a simple setup with self-signed certificates. This way you can get started with a working setup and elevate towards more sophisticated as you go. Troubleshooting </SPAN><SPAN>SNC errors can be cumbersome, so starting small with less variables and less room for error is a good idea.</SPAN></P><P>&nbsp;</P><TABLE border="1" width="100%"><TBODY><TR><TD width="100%">Be aware of latest crypto library guidance (SAPCryptoLib vs, CommonCryptoLib) published by&nbsp;<a href="https://community.sap.com/t5/user/viewprofilepage/user-id/2716">@JoeGoerlich</a>&nbsp;in <A href="https://community.sap.com/t5/technology-blogs-by-members/commoncryptolib-snc-protocol-versions-and-cipher-suites/ba-p/13518307" target="_blank">this post</A>. Verify your&nbsp;<SPAN>archive name starts with SAPCRYPTOLIB_*.sar (which refers to CCL 8.x).</SPAN></TD></TR></TBODY></TABLE><P>&nbsp;</P><H2 id="toc-hId-882852893"><SPAN>First things first: reach your private RFC interface</SPAN></H2><P><SPAN>SAP products like the SAP Cloud Connector support apps (and people) on the SAP Business Technology Platform to connect to private instances of AS ABAP systems (behind firewall, in RISE, on-premises, or on a protected hyperscaler environment) and bring the required RFC execution environment.</SPAN></P><P><SPAN>Third-party apps must overcome the same challenges. Typically, that means you will be provided with a piece of software to act as reverse invoke proxy (same as the SAP Cloud Connector) besides the “line of sight” through connected private networks from that proxy. See step 0 in the overview drawing for reference.</SPAN></P><P><SPAN>It establishes connection to your third-party app inside out, so that no inbound firewall rules or the likes need to be touched.</SPAN></P><P><SPAN>For instance, Microsoft apps like <A href="https://www.microsoft.com/download/details.aspx?id=39717" target="_blank" rel="noopener nofollow noreferrer">Azure Data Factory, Azure Synapse</A>, <A href="https://www.microsoft.com/download/details.aspx?id=105539" target="_blank" rel="noopener nofollow noreferrer">Microsoft Purview</A>, Microsoft Fabric, and <A href="https://learn.microsoft.com/power-bi/connect-data/service-gateway-onprem" target="_blank" rel="noopener nofollow noreferrer">Microsoft Power BI</A> have dedicated means to connect. These components are called Self-hosted Integration Runtime (SHIR) or On-Premises Data Gateway. Find the downloads on the individual product pages.</SPAN></P><P><SPAN>Be aware that services like Azure Functions or <A href="https://learn.microsoft.com/azure/logic-apps/connectors/sap?tabs=consumption#enable-secure-network-communications-snc" target="_blank" rel="noopener nofollow noreferrer">Azure LogicApps</A>&nbsp;have a second approach beyond the Microsoft On-premises Data Gateway. They can bring the means to execute RFC calls, provide SNC configuration, and create line-of-sight to the <A href="https://learn.microsoft.com/azure/logic-apps/connectors/sap?tabs=consumption#network-connectivity-prerequisites" target="_blank" rel="noopener nofollow noreferrer">private network through injection</A> capability in a single deployment. This way you don't need the reverse invoke proxy.</SPAN></P><P><SPAN>Each of the described solutions have individual guides on the SAP RFC setup and how to expose the configuration for SAP SNC.</SPAN></P><P><EM><SPAN>Can highly recommend my colleague </SPAN></EM><SPAN><A href="https://taylorbrazelton.com/2024/02/26/2024-02-23-setting-up-snc-between-power-apps-automate-and-sap/" target="_blank" rel="noopener nofollow noreferrer"><EM>Taylor Brazelton’s blog</EM></A><EM> for SNC from Power Platform and On-premises Data Gateway.</EM></SPAN></P><P><SPAN>Find below an SAP SNC config sequence with self-signed certificates generated by OpenSSL. Through this setup AS ABAP accepts requests protected by SNC via the SHIR.</SPAN></P><P><SPAN>I assume you have already installed the SHIR on a suitable windows machine and taken care of <A href="https://learn.microsoft.com/purview/register-scan-sapecc-source#prerequisites" target="_blank" rel="noopener nofollow noreferrer">required installations</A> like SAP Java Connector (JCo), SAP Connector for Microsoft .NET (NCo), and .NET Framework. My samples and script commands are Windows specific. However, Linux works the same way with slightly different commands.</SPAN></P><P>&nbsp;</P><H2 id="toc-hId-686339388"><SPAN>Download SAP SNC Crypto Lib to your SNC client machine</SPAN></H2><UL><LI><SPAN>Search the latest “SAPCRYPTOLIB” on SAP’s <A href="https://me.sap.com/softwarecenterviewer/67838200100200022586/MAINT" target="_blank" rel="noopener noreferrer">software center</A> (S-User with download rights required)</SPAN></LI><LI><SPAN>And extract the SAR file using <A href="https://me.sap.com/softwarecenterviewer/01200615320100002542/MAINT" target="_blank" rel="noopener noreferrer">SAPCAR</A>. Command looks something like this:</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>.\SAPCAR_1200-70007719.EXE -xvf .\SAPCRYPTOLIBP_8553-20011729.SAR -R .\..\libs\sapcryptolib</code></pre><P>&nbsp;</P><P>&nbsp;</P><UL><LI><SPAN>Find the executable sapgenpse</SPAN></LI></UL><H2 id="toc-hId-489825883">&nbsp;</H2><H2 id="toc-hId-293312378"><SPAN>Prepare your SNC client machine</SPAN></H2><UL><LI><SPAN>Create a folder to hold your SAP PSE artifacts:</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>mkdir sapsecudir cd .\sapsecudir</code></pre><P>&nbsp;</P><P>&nbsp;</P><UL><LI><SPAN>Permanently add environment variable to point at this folder</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>[Environment]::SetEnvironmentVariable("SECUDIR", "C:\sapsecudir", "Machine") # Sets the variable permentaly on the system. $env:SECUDIR = "C:\sapsecudir" # Updates the current powershell session as there currently does not exist a function to reload.</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><H2 id="toc-hId-96798873"><SPAN>Generate a certificate for your SNC client app</SPAN></H2><UL><LI><SPAN>Create folders to hold your certificates: mkdir rootCA sncCert</SPAN></LI><LI><SPAN>Generate root CA certificate: Adjust the subject as needed</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>openssl genpkey -algorithm RSA -out rootCA/ca.key.pem -pkeyopt rsa_keygen_bits:2048 openssl req -x509 -new -key rootCA/ca.key.pem -days 7305 -sha256 -extensions v3_ca -out rootCA/ca.cert.pem -subj "/O=Contoso/CN=Root CA"</code></pre><P>&nbsp;</P><P>&nbsp;</P><UL><LI><SPAN>Generate SNC client certificate and adjust subject as needed:</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>openssl genrsa -out sncCert/snc.key.pem 2048 openssl req -key sncCert/snc.key.pem -new -sha256 -out sncCert/snc.csr.pem -subj "/O=Contoso/CN=SNC"</code></pre><P>&nbsp;</P><P>&nbsp;</P><UL><LI><SPAN>Sign the SNC certificate with the root CA certificate:</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>openssl x509 -req -in sncCert/snc.csr.pem -days 3650 -CA rootCA/ca.cert.pem -CAkey rootCA/ca.key.pem -CAcreateserial -out sncCert/snc.cert.pem</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><H2 id="toc-hId--99714632"><SPAN>Establish trust between SNC client and SAP</SPAN></H2><UL><LI><SPAN>Add the SNC cert to a PKCS #12 archive file (.p12)</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>openssl pkcs12 -export -out snc.p12 -inkey sncCert\snc.key.pem -in sncCert\snc.cert.pem -certfile rootCA\ca.cert.pem</code></pre><P>&nbsp;</P><P>&nbsp;</P><UL><LI><SPAN>Create the SAP Personal Security Environment (PSE) using the container</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>.\sapgenpse.exe import_p12 -p SAPSNCSKERB.pse C:\Users\shir-admin\Documents\snc.p12</code></pre><P>&nbsp;</P><P>&nbsp;</P><P>&nbsp;</P><H3 id="toc-hId--167145418"><SPAN>Verify SAP is configured for SNC yet</SPAN></H3><P><SPAN>One way of doing that is using transaction RZ10 and browsing the parameters prefixed with SNC. See <A href="https://help.sap.com/docs/SAP_SINGLE_SIGN-ON/df185fd53bb645b1bd99284ee4e4a750/06298bf7ec7e4ae19fba6ab0c518dda1.html" target="_blank" rel="noopener noreferrer">this SAP document</A> on the required “SNC Parameters for X.509 Configuration” settings and their implications.</SPAN></P><P><SPAN>If there is no configuration yet execute the transaction SNCWIZARD and maintain settings for X.509 credentials. Take note of the SNC private key subject. The CN will be required later.</SPAN></P><P><SPAN>Add your SNC client (I named mine PRV for Microsoft Purview) to the SAP Access Control List (ACL) using transaction SNC0 and allow RFC and CPIC connections.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="MartinPankraz_2-1736697403544.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210979iBF1D0B87863E6169/image-size/large?v=v2&amp;px=999" role="button" title="MartinPankraz_2-1736697403544.png" alt="MartinPankraz_2-1736697403544.png" /></span></P><H3 id="toc-hId--363658923">&nbsp;</H3><H3 id="toc-hId--560172428"><SPAN>Import SNC client cert into SAP</SPAN></H3><UL><LI><SPAN>Use transaction STRUST</SPAN></LI><LI><SPAN>Navigate to the instance below SNC SAPCryptolib (if crossed out with a red X, create one from right-click)</SPAN></LI><LI><SPAN>Scroll down below the certificate list pane, choose import certificate and supply your snc.cert.pem file.</SPAN></LI><LI><SPAN>Click “Add to Certificate List” button</SPAN></LI><LI><SPAN>Click “Save”.</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="MartinPankraz_3-1736697403552.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210982i4D5DAC894F2F5F39/image-size/large?v=v2&amp;px=999" role="button" title="MartinPankraz_3-1736697403552.png" alt="MartinPankraz_3-1736697403552.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId--831917302"><SPAN>Download SAP cert and import into SNC client PSE</SPAN></H3><UL><LI><SPAN>From the same STRUST screen, double click the Subject line of “Own Certificate” and</SPAN></LI><LI><SPAN>Scroll down again to find the “Export Certificate” button at the bottom.</SPAN></LI><LI><SPAN>Move to your SNC client machine (where your SHIR runs), put the certificate in a secure place (in my sample it landed in a folder called sap) and run below command to import it into your PSE.</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>sapgenpse.exe maintain_pk -p SAPSNCSKERB.pse -v -a C:\sap\contoso-public-key.crt</code></pre><P>&nbsp;</P><P>&nbsp;</P><P><SPAN>Now your SAP trusts connections coming from your SHIR.</SPAN></P><P>&nbsp;</P><H2 id="toc-hId--735027800"><SPAN>Allow your SHIR process to use your SAP PSE</SPAN></H2><UL><LI><SPAN>Verify which user or service is being used by your SNC client to obtain certificate to communicate with SAP. The Purview SHIR uses the service user “NT SERVICE\DIAHostService”.</SPAN></LI><LI><SPAN>Add a credential to allow the certificate retrieval request from the PSE.</SPAN></LI></UL><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>.\sapgenpse.exe seclogin -p C:\sapsecudir\SAPSNCSKERB.pse -x your-pse-pin -O "NT SERVICE\DIAHostService"</code></pre><P>&nbsp;</P><P>&nbsp;</P><P><SPAN>Verify credentials like so</SPAN></P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>.\sapgenpse.exe seclogin -l -O "NT SERVICE\DIAHostService"</code></pre><P>&nbsp;</P><P>&nbsp;</P><P><SPAN>You can delete them like this:</SPAN></P><P>&nbsp;</P><P>&nbsp;</P><pre class="lia-code-sample language-bash"><code>.\sapgenpse.exe seclogin -d -O " NT SERVICE\DIAHostService "</code></pre><P>&nbsp;</P><P>&nbsp;</P><P><SPAN>Use the <STRONG>-h parameter to get help</STRONG> with the sapgenpse command line tool or check the command reference <A href="https://help.sap.com/docs/SAP_NETWEAVER_750/e73bba71770e4c0ca5fb2a3c17e8e229/0d9ce63bab134b39a52e340255d7650c.html" target="_blank" rel="noopener noreferrer">here</A>.</SPAN></P><P>&nbsp;</P><H1 id="toc-hId--638138298"><SPAN>Test communication using SAP SNC</SPAN></H1><P><SPAN>Navigate to your client application and supply the SNC configuration you have prepared. Some apps require an SAP user and password in addition even though providing a client certificate would be enough for a technical connection (remember: no user mapping or SSO).</SPAN></P><P><EM><SPAN>This gives you the option to further trim down access. Use transaction SU01 and the SNC tab or the maintenance view “VUSREXTID” from transaction SM30 to configure the SNC external ID (CN) to your SAP user name.</SPAN></EM></P><P><SPAN>See below sample taken from the connection configuration fly-out pane on the Azure portal UI. It can be applied, however, to any SNC client configuration. See further samples <A href="https://help.sap.com/doc/saphelp_nw75/7.5.5/en-US/ce/1dfd3d4aefd95ee10000000a114084/content.htm" target="_blank" rel="noopener noreferrer">here</A> and <A href="https://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc01703.0222/doc/html/fre1292886445861.html" target="_blank" rel="noopener nofollow noreferrer">here</A>.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="MartinPankraz_4-1736697403557.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/210983iBFAF35BE9B7B3379/image-size/medium?v=v2&amp;px=400" role="button" title="MartinPankraz_4-1736697403557.png" alt="MartinPankraz_4-1736697403557.png" /></span></P><P>&nbsp;</P><P><SPAN>Trigger “Test connection” and marvel at the SNC secured communication test from Microsoft Purview to AS ABAP</SPAN><span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span></P><P><SPAN>Or go even a step further and call your first RFC. RFC_PING or STFC_CONNECTION might be a suitable one in case your target is not yet operational or not identified yet.</SPAN></P><P>&nbsp;</P><H1 id="toc-hId--834651803"><SPAN>Hints on Troubleshooting</SPAN></H1><UL><LI><SPAN>First, try to connect from your client to AS ABAP without SNC to ensure that networking is properly configured already. Be aware of <A href="https://help.sap.com/docs/Security/575a9f0e56f34c6e8138439eefc32b16/616a3c0b1cc748238de9c0341b15c63c.html" target="_blank" rel="noopener noreferrer">SAP RFC ports</A> (ZZ placeholder represents your SAP instance number, e.g. 00 or 01 often) and check firewall accordingly if needed.</SPAN><UL><LI><SPAN>32ZZ and 33ZZ for direct RFC connections</SPAN></LI><LI><SPAN>48ZZ for SNC secured RFC connections</SPAN></LI></UL></LI><LI><SPAN>Verify SNC status from transaction SM51 -&gt; click “SNC Status” button to ensure it is fully configured</SPAN></LI><LI><SPAN>Consult the <A href="https://community.sap.com/t5/application-development-blog-posts/report-zsm04000-snc-zrsusr000-620-show-snc-status-of-current-user-sessions/ba-p/13027982" target="_blank">blog series</A> from @<A href="https://community.sap.com/t5/user/viewprofilepage/user-id/360" target="_blank">Frank_Buchholz</A> on more sophisticated approaches to verify individual SNC connections. For instance, report “<A href="https://github.com/SAP-samples/security-services-tools" target="_blank" rel="noopener nofollow noreferrer">ZSM04000_SNC</A>” shows more details.</SPAN></LI><LI><SPAN>For those of you using <A href="https://help.sap.com/docs/SAP_NETWEAVER_750/1ca554ffe75a4d44a7bb882b5454236f/ab35e1c69f744d69a4fcf4ca93284e0c.html" target="_blank" rel="noopener noreferrer">SAP UCON</A> may consult the SNC connectivity status there.</SPAN></LI><LI><SPAN>Closing above mentioned RFC ports (32ZZ, 33ZZ) on the proxy VM firewall does the trick to verify if SNC connection is opened. Intentionally “breaking” your SNC config by mistyping the SNC partner name for instance could give you another indication on a functional setup.</SPAN></LI></UL><P>&nbsp;</P><H1 id="toc-hId--1031165308"><SPAN>Final Words</SPAN></H1><P><SPAN>That’s a wrap </SPAN><span class="lia-unicode-emoji" title=":burrito:">🌯</span><SPAN>. You learned today how to secure your technical RFC connections from third party apps to AS ABAP systems using SNC. The guide keeps it simple so you can establish a stable setup base from which to iterate on more complex setups confidently </SPAN><span class="lia-unicode-emoji" title=":smiling_face_with_smiling_eyes:">😊</span><SPAN>Generate SOAP services for your RFCs and use TLS in case SNC is not an option.</SPAN></P><P><SPAN>By the way: When introducing an API Management solution between your 3rd party app and the SOAP service on AS ABAP you may use OAuth2, or OpenID Connect on the client. You still need to translate on the API Management layer to an auth mechanism that <A href="https://help.sap.com/docs/SAP_NETWEAVER_750/f7dd32926c1c4fcf889a4303d833a22b/cf507f42805444f3ad1caf430ca4a221.html" target="_blank" rel="noopener noreferrer">AS ABAP supports</A>. Either way a step forward in securing your SAP connections.</SPAN></P><P><SPAN>Happy integrating with SAP!</SPAN></P><P><SPAN>#Kudos again to <A href="https://www.linkedin.com/in/savas-akgol-713b3915/" target="_self" rel="nofollow noopener noreferrer">Savas Akgol</A>,&nbsp;<a href="https://community.sap.com/t5/user/viewprofilepage/user-id/171519">@MartinRaepple</a>, and&nbsp;<a href="https://community.sap.com/t5/user/viewprofilepage/user-id/360">@Frank_Buchholz</a>&nbsp;for helping with some&nbsp; of the hard parts&nbsp;<span class="lia-unicode-emoji" title=":folded_hands:">🙏</span></SPAN></P><P><SPAN>&nbsp;</SPAN></P><P><SPAN>Cheers</SPAN></P><P><SPAN>Martin</SPAN></P> 2025-01-12T17:20:02.514000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/communicate-from-a-java-application-to-abap-via-websocket-rfc-using-jco/ba-p/13981498 Communicate from a Java Application to ABAP via WebSocket RFC using JCo - Migration Guide 2025-01-21T19:20:20.825000+01:00 simon_luser https://community.sap.com/t5/user/viewprofilepage/user-id/771659 <P><A href="https://community.sap.com/t5/technology-blogs-by-sap/websocket-rfc-rfc-for-the-internet/ba-p/13502531" target="_blank">WebSocket RFC</A> is available for a while now. Continue reading, if</P><OL><LI>you want to communicate from an external Java application to an ABAP-based system via this new protocol using the&nbsp;<A href="https://support.sap.com/en/product/connectors/jco.html" target="_blank" rel="noopener noreferrer">JCo library</A>.</LI><LI>you have an existing JCo setup using classic CPIC-based RFC and want to migrate.</LI></OL><H1 id="toc-hId-950224196">Adjusting the destination</H1><P>For specifying the destination, instead of providing properties for application server logon (<SPAN><EM>jco.client.ashost</EM>,&nbsp;<EM>jco.client.sysnr</EM>) or message server logon (<EM>jco.client.mshost</EM>,&nbsp;<EM>jco.client.msserv</EM>,&nbsp;<EM>jco.client.r3name</EM>), the f</SPAN>ollowing properties must be provided:</P><UL><LI><SPAN><STRONG>jco.client.wshost</STRONG>: the hostname of the target system</SPAN></LI><LI><SPAN><STRONG>jco.client.wsport</STRONG>: the port for HTTPS/WSS (WebSocket Secure) of the target system</SPAN></LI></UL><P><SPAN>Optionally, you can also specify</SPAN></P><UL><LI><SPAN><STRONG>jco.client.tls_client_certificate_logon</STRONG>: If set to 1 this property enables to logon at the backend via the X.509 client&nbsp;certificate that is used in the TLS handshake (mTLS). An associated user or mapping rule must be defined at the backend.</SPAN></LI></UL><H1 id="toc-hId-753710691">Extending the implementation</H1><P>WebSocket RFC is based on TLS, thus a PKI infrastructure is required to be setup. To achieve that, following methods from the JCo interface <EM>DestinationDataProvider</EM>&nbsp;must be implemented:</P><P>&nbsp;</P><pre class="lia-code-sample language-java"><code>SSLContext getSSLContext(String destinationName)</code></pre><P>&nbsp;</P><P>This method returns a&nbsp;<EM>javax.net.ssl.SSLContext</EM> instance to JCo, which is used to create the TLS session for a given destination. How such an instance is created is up to the application - we are going to describe a simple use case in which all keys and CAs are stored in a local p12 file (<EM>p12FilePath</EM>) and the password is read from a secured database.</P><P>&nbsp;</P><pre class="lia-code-sample language-java"><code>SSLContext loadSSLContextFromFile() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyManagementException { File p12File = new File(p12FilePath); try (InputStream p12FileStream = new BufferedInputStream(new FileInputStream(p12File))) { KeyStore ks = KeyStore.getInstance("PKCS12"); char[] pwd = SecuredDatabaseConnection.readPassword(); ks.load(p12FileStream, pwd); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, pwd); // delete the plain text password from the heap memory as soon as possible Arrays.fill(pwd, (char) 0); pwd = null; TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); return sslContext; }</code></pre><P>&nbsp;</P><P>(Optionally) If&nbsp;<SPAN><STRONG>jco.client.tls_client_certificate_logon&nbsp;</STRONG>is used, the API below must be implemented additionally:</SPAN></P><P>&nbsp;</P><pre class="lia-code-sample language-java"><code>X509Certificate getClientCertificate(String destinationName)</code></pre><P>&nbsp;</P><P>This method must return the <EM>java.security.cert.X509Certificate</EM> instance of the client certificate used for logon. It must be the one provided in the <EM>SSLContext</EM>, which is used during the TLS handshake.</P><H1 id="toc-hId-557197186">Setting up Trust</H1><H2 id="toc-hId-489766400">Creating the p12 File</H2><P>Create a p12 file with a private key using a tool like <A href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html" target="_blank" rel="noopener nofollow noreferrer">keytool</A> or <A href="https://docs.openssl.org/1.1.1/man1/pkcs12/" target="_blank" rel="noopener nofollow noreferrer">OpenSSL</A>. Create a CSR and import the CA response. Furthermore, import the CA certificate from the ABAP system which has been exported (see next section).</P><H2 id="toc-hId-293252895">Configuring trust in ABAP</H2><P>Navigate to transaction STRUST and select "SSL-Server Standard". Select the own certificate and export it. For more information, see also <A href="https://help.sap.com/docs/SAP_NETWEAVER_750/e73bba71770e4c0ca5fb2a3c17e8e229/4923501ebf5a1902e10000000a42189c.html" target="_blank" rel="noopener noreferrer">here</A>. Also, import the CA certificate from the p12 file and add it to the certificate list, so that mutual trust can be established.</P><H1 id="toc-hId--32343329">Using WebSocket RFC in BTP</H1><P>If you use JCo in BTP in conjunction with the Destination Service and you want to use WebSocket RFC to call publicly exposed endpoints, you can skip the above "Extending the implementation" part. This integration is already implemented by SAP in the supported environments. You can follow the steps in the <SPAN><A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/cloud-configure-rfc-destination" target="_blank" rel="noopener noreferrer">BTP Connectivity Service documentation</A></SPAN> on how to configure the Destination Service accordingly.</P> 2025-01-21T19:20:20.825000+01:00 https://community.sap.com/t5/technology-blog-posts-by-members/abap-adaptation-for-any-middleware-to-cpi-is-migration-rfc-to-webservice/ba-p/14105577 ABAP Adaptation for Any Middleware to CPI/IS Migration ( RFC to Webservice ) 2025-05-20T16:14:40.004000+02:00 Hashini https://community.sap.com/t5/user/viewprofilepage/user-id/1419019 <P><STRONG>1.Introduction:</STRONG></P><P>This document provides an in-depth overview of the necessary changes in ABAP development when migrating from any middleware platform to SAP CPI. It particularly addresses the migration of RFC-based communication in middleware to SOAP-based web services in CPI.</P><P><STRONG>2.Background:</STRONG></P><P>The integration platform that enables communication between SAP and external systems. In any middleware, RFC adapters are commonly used to interact with remote systems through RFCs. However, with the shift to SAP CPI/IS, the integration landscape changes, and CPI/IS does not support sender RFCs, so &nbsp;it is necessary to refactor and convert these RFC calls into SOAP web services.</P><P><STRONG>3.Transition to SAP CPI:</STRONG></P><P>In CPI, communication is predominantly based on HTTP/SOAP or REST protocols. Therefore, the ABAP function modules that were exposed as RFCs in integration platform must now be exposed as <STRONG>SOAP web services</STRONG> to be compatible with CPI’s integration model.</P><P><STRONG>4.Why Convert RFC to a SOAP Web Service Rather Than Using a Wrapper?</STRONG></P><P>When a wrapper is created for a sender or receiver RFC, SAP automatically configures the service provider (inbound interface) in SOAMANAGER, thereby generating the web service from the scratch.<BR /><BR /><STRONG>5.ABAP Development Steps - Replacing RFC with SOAP Web Services:<BR /></STRONG></P><P><STRONG>&nbsp; &nbsp;5.1. Obtain the WSDL file from the RFC in SAP or from Integration team.</STRONG></P><P><STRONG>&nbsp; &nbsp; &nbsp; 5.1.1.In SE37, enter the RFC to convert to SOAP.</STRONG></P><P><STRONG>&nbsp; &nbsp; &nbsp; 5.1.2.</STRONG>Go to <STRONG>Utilities</STRONG> -&gt; <STRONG>More Utilities</STRONG> -&gt; <STRONG>Create Web Service</STRONG> -&gt; <STRONG>From Function Module</STRONG>.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_0-1746429056919.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257494i17CFCB0BD135FEAF/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_0-1746429056919.png" alt="Hashini_0-1746429056919.png" /></span></P><P>&nbsp; &nbsp; &nbsp; &nbsp;5.1.3.Enter the RFC name and description, then click <STRONG>Next</STRONG>.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_1-1746429146623.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257495i5C5301181E8BC2E2/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_1-1746429146623.png" alt="Hashini_1-1746429146623.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_3-1746434065390.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257524i0393504AFBBC435E/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_3-1746434065390.png" alt="Hashini_3-1746434065390.png" /></span></P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_2-1746433768602.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257521iC8106AAD1AD49529/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_2-1746433768602.png" alt="Hashini_2-1746433768602.png" /></span>&nbsp; &nbsp; &nbsp; &nbsp; 5.1.4.Fill in the details and click <STRONG>Finish</STRONG>.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;The screen will appear as shown below.</P><P>&nbsp; &nbsp; &nbsp; &nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_4-1746434144573.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257525i093DF027A1CCFC82/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_4-1746434144573.png" alt="Hashini_4-1746434144573.png" /></span>&nbsp; &nbsp; &nbsp; &nbsp; 5.1.5.Click on the <STRONG>WSDL</STRONG> tab to retrieve the WSDL file and modify the wsdl file.<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_5-1746434261354.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257528i08218480B43EBEB5/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_5-1746434261354.png" alt="Hashini_5-1746434261354.png" /></span><BR />&nbsp; &nbsp;&nbsp;</P><P><STRONG>&nbsp; &nbsp; &nbsp;5.2. Modify the WSDL to an asynchronous structure.<BR />&nbsp; &nbsp; &nbsp;</STRONG><STRONG>5.2.1. Why to modify the wsdl structure?</STRONG><STRONG>&nbsp; &nbsp; &nbsp;&nbsp;</STRONG></P><P>The WSDL structure used in PI/PO follows a synchronous pattern, with both request and response. When uploading the same file while creating a web service, SAP expects a response from the middleware. To convert it to asynchronous, the WSDL structure must be modified.<BR /><BR />Before modification of WSDL : ( It has both input and output parameter )</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_6-1746434525224.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257533i4E7AC59A8E7B8AC7/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_6-1746434525224.png" alt="Hashini_6-1746434525224.png" /></span></P><P>After modification of WSDL : ( It has only input parameter )</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_7-1746434620939.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257536iE2EAD6C5B22830C6/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_7-1746434620939.png" alt="Hashini_7-1746434620939.png" /></span></P><P>&nbsp; &nbsp; &nbsp;5.2.2. <STRONG>How it can be modified?</STRONG>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; At the end of &lt;/wsdl:types&gt; tag, add the below template and update the required details:&nbsp;<BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Replace&nbsp; ZTEST in the template with the actual RFC name. &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<BR /><BR />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;wsdl:message name="ZTEST"&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;wsdl:part name=" ZTEST " element="tns: ZTEST "/&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/wsdl:message&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;wsdl:portType name=" ZTEST"&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;wsp:Policy&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;wsp:PolicyReference URI="#IF_IF_ ZTEST "/&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/wsp:Policy&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;wsdl:operation name=" ZTEST"&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;wsp:Policy&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;wsp:PolicyReference URI="#OP_IF_OP_ ZTEST"/&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/wsp:Policy&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;wsdl:input message="tns: ZTEST"/&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/wsdl:operation&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/wsdl:portType&gt;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/wsdl:definitions&gt;<BR /><BR /></P><P><STRONG>5.3. Upload the WSDL and create the web service in SE80.</STRONG></P><P>&nbsp; &nbsp; &nbsp; 5.3.1.Navigate to sproxy tcode and click on create button.<STRONG><BR /><BR /></STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_8-1746440106759.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257568i1DFF3324020F888B/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_8-1746440106759.png" alt="Hashini_8-1746440106759.png" /></span>&nbsp; &nbsp; &nbsp;&nbsp;<BR />&nbsp; &nbsp; &nbsp; 5.3.2.Click on service consumer radio button and then continue.</P><P>&nbsp; &nbsp; &nbsp;&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_9-1746440159366.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257570iB046C320BCBA7330/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_9-1746440159366.png" alt="Hashini_9-1746440159366.png" /></span><BR />&nbsp; &nbsp; &nbsp; 5.3.3.Click on service External WSDL/Schema and then continue.</P><P>&nbsp; &nbsp; &nbsp; &nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_10-1746440204546.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257571i37808EEE26AFA571/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_10-1746440204546.png" alt="Hashini_10-1746440204546.png" /></span><BR />&nbsp; &nbsp; &nbsp; 5.3.4.Click on local file and then continue.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_11-1746440243240.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257573i5B08B741944E69E4/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_11-1746440243240.png" alt="Hashini_11-1746440243240.png" /></span>&nbsp; &nbsp; &nbsp;&nbsp;<BR />&nbsp; &nbsp; &nbsp; 5.3.5.Upload the wsdl file and click on continue.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_12-1746440285961.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257575i5F547837BE5610DA/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_12-1746440285961.png" alt="Hashini_12-1746440285961.png" /></span><BR />&nbsp; &nbsp; &nbsp; 5.3.6.Provide the package name and then the TR details and then continue .</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_13-1746440335494.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257576iF1AF9C50FE69CBC0/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_13-1746440335494.png" alt="Hashini_13-1746440335494.png" /></span><BR />&nbsp; &nbsp; &nbsp; 5.3.7.Click on complete and then save and activate the service.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_14-1746440379651.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257577iCA328256692193FC/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_14-1746440379651.png" alt="Hashini_14-1746440379651.png" /></span><BR />5.4.Use the "Where Used" function to identify the related report, function module, or class of the RFC.</P><P>5.5.Replace the RFC code with the corresponding SOAP web service code,ensuring all required parameters are passed as in the original RFC.</P><P><STRONG>RFC Code :</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_15-1746440486989.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257578i555CDD586993C77D/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_15-1746440486989.png" alt="Hashini_15-1746440486989.png" /></span></P><P><STRONG>SOAP Code:</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_16-1746440532648.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257579i5A39405B8F356868/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_16-1746440532648.png" alt="Hashini_16-1746440532648.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_17-1746440569650.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257581iD69CCA7BBD8FF9F7/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_17-1746440569650.png" alt="Hashini_17-1746440569650.png" /></span></P><P>5.6.Configure the web service in SOAMANAGER.</P><P>&nbsp; &nbsp; &nbsp; 5.6.1.Navigate to SOAMANAGER tcode and click on <STRONG>web service configuration.</STRONG></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_18-1746440621733.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257583i8EC9398FABA20172/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_18-1746440621733.png" alt="Hashini_18-1746440621733.png" /></span></P><P>&nbsp; &nbsp; &nbsp; 5.6.2.Provide and select the web service name</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_19-1746440787129.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257590iD0D16126F6ECFA26/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_19-1746440787129.png" alt="Hashini_19-1746440787129.png" /></span></P><P>&nbsp; &nbsp; 5.6.3. Click on the create button manual configuration to create a logical port for the webservice.&nbsp;Provide the Port name and description.</P><P>&nbsp;</P><P>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_20-1746440857861.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257591i7C43A09A50F4909D/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_20-1746440857861.png" alt="Hashini_20-1746440857861.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_21-1746440936281.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257593i8DB3A9A41CFAD1B5/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_21-1746440936281.png" alt="Hashini_21-1746440936281.png" /></span><BR />&nbsp; &nbsp; &nbsp; &nbsp; 5.6.4. In the consumer security tab, give the s-user ID and password and click next.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_22-1746440977144.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257594iC92E2E9662EAFD1C/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_22-1746440977144.png" alt="Hashini_22-1746440977144.png" /></span></P><P>&nbsp; &nbsp; &nbsp; &nbsp;5.6.5. Provide the correct endpoint in the URL tab and click next.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_23-1746441032712.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257595i761E4B889B87C256/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_23-1746441032712.png" alt="Hashini_23-1746441032712.png" /></span></P><P>&nbsp; &nbsp; &nbsp; 5.6.6. In the Messaging tab, select suppress id transfer in Message ID Protocol and SAP RM in&nbsp;RM&nbsp;Protocol tab and click next.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_24-1746441202281.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257596i5493356F49295930/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_24-1746441202281.png" alt="Hashini_24-1746441202281.png" /></span></P><P>&nbsp; &nbsp; &nbsp; 5.6.7. Click on finish to complete the setting.</P><P>&nbsp; &nbsp; &nbsp; 5.6.8: Click on ping test for the successful setup.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Hashini_25-1746446817247.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/257647iDA5E5450746CCCF3/image-size/medium?v=v2&amp;px=400" role="button" title="Hashini_25-1746446817247.png" alt="Hashini_25-1746446817247.png" /></span></P><P>&nbsp; &nbsp;&nbsp;</P> 2025-05-20T16:14:40.004000+02:00 https://community.sap.com/t5/application-development-and-automation-blog-posts/function-expression-in-business-rule-framework-brf/ba-p/14156170 Function Expression in Business Rule Framework (BRF+) 2025-08-12T11:28:52.458000+02:00 manoharreddy478 https://community.sap.com/t5/user/viewprofilepage/user-id/152690 <P>Function in BRF+:</P><P><SPAN>A function is the&nbsp;</SPAN>rule interface<SPAN>&nbsp;in BRF+ and acts as a link between the application code and the BRF+ code. A function carries a context and a result. It imports the context from the calling application and passes the context data to the assigned top expression or ruleset for further processing.</SPAN></P><P><SPAN>Create an BRF+ application or chose the application in which you wanted to add function Expression.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Right click on the application and select create &gt; Function</SPAN><SPAN>&nbsp;</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="manoharreddy478_0-1752824529026.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288460i61EA79C34E910895/image-size/large?v=v2&amp;px=999" role="button" title="manoharreddy478_0-1752824529026.png" alt="manoharreddy478_0-1752824529026.png" /></span></P><P>&nbsp;</P><P><SPAN>Provide the function name, text and short text.</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="manoharreddy478_1-1752824529027.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288459iB99FA991E1A5E86A/image-size/large?v=v2&amp;px=999" role="button" title="manoharreddy478_1-1752824529027.png" alt="manoharreddy478_1-1752824529027.png" /></span></P><P><SPAN>Click on create and&nbsp;</SPAN><SPAN>navigate to object to save and activate the object.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="manoharreddy478_2-1752824529029.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288461iF1CC269E100DFB38/image-size/large?v=v2&amp;px=999" role="button" title="manoharreddy478_2-1752824529029.png" alt="manoharreddy478_2-1752824529029.png" /></span></P><P>&nbsp;</P><P><SPAN>Once clicked, it will navigate to the above screen. Here you have to assign the result data object based on the context data objects.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Types of Mode:</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Function mode:</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>In functional mode, function execution starts with the assigned top expression. From this top expression, the processing may run through any number of nested subexpressions until a result is returned.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Event mode:</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>In event mode, the function is associated with a list of rulesets that are executed according to their execution priority and their position in the list.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Function and Event mode:</SPAN></P><P><SPAN>This mode is a combination of the modes mentioned above. At runtime, the function starts processing the assigned top expression. Once the expression evaluation is finished, function execution continues with the associated rulesets.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Analytical Mode:</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>It is mainly related to the Hana rules framework which is relevant to the runtime operations.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>&nbsp;Signature</SPAN></P><P><SPAN>The function signature consists of two parts:</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Context</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>The context is a container for data objects that you can assign as import parameters for the function. You choose the context data objects of a function according to the requirements of the calling application by which the BRF+ function is invoked. Also, the context data objects of a function define the scope of objects that can be accessed by the expressions that are evaluated during function execution.</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Result</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>The result data object returns a result value that has been calculated by the expressions of which the function consists .</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Note: For further in event mode, the result object is automatically set to the predefined actions table where the actions are recorded that have been triggered by the assigned rulesets.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Code Generation:</SPAN></P><P><SPAN>BRF+ provides a built-in code generation facility used to compile source code for as many rule constructs in a function as possible. With the help of generated code, BRF+ rules can be executed significantly faster than in interpretation mode.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Simulation:</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>You can simulate the function processing to test the function's behavior in a sandbox environment. Here, you can gain an in-depth insight into the system status for every single step the system takes during function processing.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Trace</SPAN></P><P><SPAN>In BRF+, you can request the system to create a processing log to keep track of all processing steps during function execution. The trace information is stored in the system and can be reviewed at any point in time.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Trace will be stored in Trace tables FDT_TRACE_* </SPAN></P><P><SPAN>Generation Services</SPAN></P><P><SPAN>For a BRF+ function, you can take advantage of different services that automatically generate code and other objects that are needed to bridge the gap between the ABAP backend system where a BRF+ function is hosted and other systems or environments that wish to access BRF+. The different services available address different usage scenarios. These can be categorized as follows:</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Code Templates</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>A code template is a predefined snippet of ABAP code that you can use to call a BRF+ function from your application in the same system.</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Generate&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Function Module</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>You can use a generated RFC-enabled function module to call a BRF+ function that resides in a remote backend system. This is useful in cases where you cannot bring BRF+ and the calling application into the same system — be it for technical reasons (for example, different releases) or for organizational reasons (for example, missing authorization to develop in the remote system).</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Web Service</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>You can use a generated web service to call a BRF+ function from a web application that is not ABAP-based, or that you can only integrate via its exposed services interface. From a technical point of view, web service generation is reusing the function module generation component of BRF+ and generates additional system objects needed for service enablement.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Here we will work on Function mode example:</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="manoharreddy478_3-1752824529030.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288463i1191B0572209180D/image-size/large?v=v2&amp;px=999" role="button" title="manoharreddy478_3-1752824529030.png" alt="manoharreddy478_3-1752824529030.png" /></span></P><P><SPAN>Assign the top expression and in context add the required objects and finally assign result object suitable.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Top Expression:&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Its is pre-condition of the function which will evaluate the number of nested expressions to find the result.</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>To execute the function click on simulation.</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="manoharreddy478_4-1752824529031.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288462i84A6CAE70B8E7C9C/image-size/large?v=v2&amp;px=999" role="button" title="manoharreddy478_4-1752824529031.png" alt="manoharreddy478_4-1752824529031.png" /></span></P><P><SPAN>Click on continue</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="manoharreddy478_5-1752824529032.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288464iE75AFDCD26B125E5/image-size/large?v=v2&amp;px=999" role="button" title="manoharreddy478_5-1752824529032.png" alt="manoharreddy478_5-1752824529032.png" /></span></P><P><SPAN>Select the input true or false and click on execute</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Result :</SPAN><SPAN>&nbsp;</SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="manoharreddy478_6-1752824681872.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/288466i7DB353D19356CE45/image-size/large?v=v2&amp;px=999" role="button" title="manoharreddy478_6-1752824681872.png" alt="manoharreddy478_6-1752824681872.png" /></span></P><P>Note : All the objects created will be stored in FDT_* tables&nbsp;</P><P>Conclusion:&nbsp;</P><P>Function provides a built-in code generation facility used to compile source code for as many rule constructs in a function as possible<BR />Function is the most important BRF+ object and it represents a decision service , which is the element that is in fact invoked by the application and&nbsp;the entire application is invoked by function to stimulate and provide the output we can invoke using the code generation to create report program for executing in GUI.<BR />we can perform pre-conditional and event of action related condition's like rules for executing in the based on the specified rule using the type of modes in the function expression.</P><P><SPAN>&nbsp;</SPAN></P><P><SPAN>&nbsp;</SPAN></P> 2025-08-12T11:28:52.458000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/abap-s-parallel-processing-frameworks-practical-guide-to-performance-tuning/ba-p/14224397 ABAP's Parallel Processing Frameworks: Practical Guide to Performance Tuning of Mass Data Processing 2025-09-29T08:52:47.138000+02:00 marc_steinert https://community.sap.com/t5/user/viewprofilepage/user-id/892436 <P>While working on a project to optimize a standard SAP report that struggled with large data volumes, I took a deep dive into <STRONG>performance tuning</STRONG> in ABAP, specifically focusing on <STRONG>parallel processing</STRONG>. This journey led me to a comprehensive analysis of the various methods SAP provides for running processes in parallel.</P><P>I discovered that parallel processing in ABAP is achieved using one of two core technologies. The first is the <STRONG>Remote Function Call (RFC)</STRONG>, where both <STRONG>asynchronous (aRFC)</STRONG> and <STRONG>background (bgRFC)</STRONG> variants can be used to run tasks in parallel. The second technology is based on &nbsp;<STRONG>background processes</STRONG>. To make implementation easier, several <STRONG>frameworks</STRONG> have been built on top of these technologies, simplifying the development process.</P><P>This blog post is a <STRONG>summary</STRONG> of the theoretical research I conducted for my bachelor's thesis. Its goal is to provide a <STRONG>comprehensive overview</STRONG> of the different technologies and the six key frameworks I identified. Think of it as a practical guide to help you choose the most suitable framework for your needs, with linked resources for anyone who wants to dive deeper into a specific topic.</P><H3 id="toc-hId-1890036543"><STRONG>The Landscape of Parallel Processing in ABAP</STRONG></H3><P>As mentioned in the introduction, parallel processing in ABAP is based on two core technologies. To simplify their use, multible frameworks have been developed for easier implementation. The following table provides an overview of these technologies and their corresponding frameworks:</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="marc_steinert_0-1758550065480.png" style="width: 706px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/318006iFE283EECD9A1C02A/image-dimensions/706x145?v=v2" width="706" height="145" role="button" title="marc_steinert_0-1758550065480.png" alt="marc_steinert_0-1758550065480.png" /></span></P><P>Now, let's explore how each of these core technologies enables parallel processing.</P><H4 id="toc-hId-1822605757"><STRONG>Asynchronous Remote Function Call (aRFC)</STRONG></H4><P>The <STRONG>Asynchronous Remote Function Call</STRONG> is one of the older and established SAP technology for parallel processing in ABAP. It works by starting a session in a separate <STRONG>dialog work process</STRONG>, which then executes a function module in parallel with the main program. The calling program does not wait for the function to finish and continues its own processing immediately.</P><P>By starting multiple aRFCs in a row, you can achieve a significant parallelization effect, as each call runs simultaneously in its own process. This is implemented using the <EM>STARTING NEW TASK</EM> addition to the standard <EM>CALL FUNCTION</EM> statement. A example call could look like this:</P><PRE>CALL FUNCTION '&lt;function_module_name&gt;' STARTING NEW TASK '&lt;task_name&gt;' DESTINATION IN GROUP &lt;server_group&gt; PERFORMING &lt;callback_form&gt; ON END OF TASK.</PRE><P>For a more detailed guide on aRFCs, check out these resources:</P><UL><LI>Book: Gahm, H. (2009): ABAP Performance Tuning</LI><LI><A href="https://pdfcoffee.com/5-rfc-types-in-abap-pdf-free.html" target="_self" rel="nofollow noopener noreferrer">Jolfaei, M. A. and Neuwirt, E. (2006): Master the five remote function call (RFC) types in ABAP</A></LI><LI><A href="https://help.sap.com/doc/saphelp_em92/9.2/en-US/48/89673284b84e6fe10000000a421937/content.htm?no_cache=true" target="_self" rel="noopener noreferrer">SAP Help Portal: Asynchronous RFC (aRFC)</A></LI><LI><A href="https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/753088fc00704d0a80e7fbd6803c8adb/489aa5b948c673e8e10000000a42189b.html" target="_self" rel="noopener noreferrer">SAP Help Portal: Parallel Processing with Asynchronous RFC</A></LI></UL><P>&nbsp;</P><H4 id="toc-hId-1626092252"><STRONG>Background Remote Function Call (bgRFC)</STRONG></H4><P>The <STRONG>Background Remote Function Call</STRONG> is a newer method for parallelization. While it also uses dialog work processes for execution like the aRFC, its operational logic is quite different.</P><P>Instead of executing immediately, a bgRFC call is first saved to a <STRONG>persistent queue</STRONG> in the database. The actual processing is only triggered by an explicit <EM>COMMIT WORK</EM> statement and is managed by a dedicated <STRONG>scheduler</STRONG>. This approach makes it possible to execute tasks with an <STRONG>"Exactly Once"</STRONG> or even an <STRONG>"Exactly Once in Order"</STRONG> guarantee, which provides a high degree of reliability.</P><P>The implementation is nearly identical to that of an aRFC. The key difference is the use of the <EM>IN BACKGROUND UNIT</EM> statement, which groups one or more function calls into a single, logical unit of work.</P><PRE>CALL FUNCTION '&lt;function_module_name&gt;' IN BACKGROUND UNIT &lt;unit_object&gt;.</PRE><P>You can find more information about this technology here:</P><UL><LI><A href="https://support.sap.com/en/alm/sap-focused-run/expert-portal/integration-cloud-monitoring/bgrfc.html" target="_self" rel="noopener noreferrer">SAP Support: bgRFC</A></LI><LI><A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/753088fc00704d0a80e7fbd6803c8adb/48927c2caa6b17cee10000000a421937.html" target="_self" rel="noopener noreferrer">SAP Help Portal: bgRFC (Background Remote Function Call)</A></LI></UL><P>&nbsp;</P><H4 id="toc-hId-1429578747"><STRONG>Background Processes</STRONG></H4><P>Using dedicated <STRONG>Background Processes</STRONG> is another established method for achieving parallelism in SAP Systems, especially suitable for long-running and resource-intensive tasks that can be clearly divided.</P><P>Parallelizing with background processes follows the same core principle as with aRFCs: multiple tasks are started to run simultaneously. This can be achieved in two main ways. The first approach is done purely through configuration. Here, an administrator can manually schedule the same ABAP program multiple times, where each parallel <STRONG>job</STRONG> uses a unique <STRONG>variant</STRONG> with a different dataset<STRONG>.</STRONG></P><P>The second approach is to implement this parallelization within a single ABAP program. This is done using a set of function modules that control the job lifecycle:</P><UL><LI><EM><STRONG>JOB_OPEN</STRONG></EM> creates a new job.</LI><LI><EM><STRONG>JOB_SUBMIT</STRONG></EM> adds the program and its variant as a step.</LI><LI><EM><STRONG>JOB_CLOSE</STRONG></EM> releases the job to the system for execution.</LI></UL><P>For more details on implementing parallel background jobs, check out these resources:</P><UL><LI><A href="https://community.sap.com/t5/application-development-and-automation-blog-posts/parallel-processing-with-background-jobs-in-sap/ba-p/14001745" target="_self">SAP Community (2025): Parallel Processing with Background Jobs in SAP</A></LI><LI><A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/7bfe8cdcfbb040dcb6702dada8c3e2f0/4d95304dd1b83c46e10000000a42189e.html?locale=en-US" target="_self" rel="noopener noreferrer">SAP Help Portal: Programming with the Background Processing System (BC-CCM-BTC)</A></LI><LI><A href="https://community.sap.com/t5/application-development-and-automation-blog-posts/parallel-processing-of-background-jobs-in-sap/ba-p/13244439" target="_self">SAP Community (2014):&nbsp;Parallel processing of background jobs in SAP&nbsp;</A></LI></UL><P>&nbsp;</P><H3 id="toc-hId-1103982523"><STRONG>Frameworks for Easier Implementation</STRONG></H3><P>While the core technologies provide the fundamental mechanisms for parallel processing, implementing them directly requires handling details like load balancing, package creation and managing parallel tasks. To simplify this process, SAP provides several <STRONG>frameworks</STRONG> that build on these technologies. These frameworks offer a structured, reusable and often easier way to implement robust parallel processing.</P><P>To select the most suitable framework, the following decision matrix based on the Qualitative Weight and Summ (QWS) method provides a visual comparison. The <STRONG>darker the green shade</STRONG>, the better a framework fulfills a specific criterion. Please note that this matrix reflects my subjective evaluation for a specific use case. Your assessment will likely differ based on your project's unique requirements.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="marc_steinert_1-1758550429007.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/318022i6DE4D8A1A7502555/image-size/large?v=v2&amp;px=999" role="button" title="marc_steinert_1-1758550429007.png" alt="marc_steinert_1-1758550429007.png" /></span></P><P><STRONG>Evaluation Criteria Explained</STRONG></P><P>Here is a brief summary of each criterion used in the matrix:</P><UL><LI><STRONG>Platform Compatibility:</STRONG> Runs on both SAP ECC and S/4HANA systems.</LI><LI><STRONG>Timeout Robustness:</STRONG> Handles long-running tasks without timing out.</LI><LI><STRONG>Package Creation:</STRONG> Automatically divides data into work packages.</LI><LI><STRONG>Configurable Package Size:</STRONG> Allows the developer to define the size of work packages.</LI><LI><STRONG>Parallel Execution:</STRONG> Automatically starts and manages the execution of parallel tasks.</LI><LI><STRONG>Result Aggregation:</STRONG> Helps collect and consolidate results from parallel tasks.</LI><LI><STRONG>Multi-Server Function:</STRONG> Can distribute tasks across multiple application servers.</LI><LI><STRONG>Processing Server Selection:</STRONG> Allows specifying a server or server group for execution.</LI><LI><STRONG>Load Balancing:</STRONG> Automatically distributes tasks based on system load.</LI><LI><STRONG>System Load Control:</STRONG> Allows setting limits on the maximum system resources used.</LI><LI><STRONG>Implementation Effort:</STRONG> The complexity and time required to implement the framework.</LI><LI><STRONG>Documentation Quality:</STRONG> The availability and quality of supporting documentation.</LI></UL><P>Now lets have a look at the individual Frameworks.</P><P>&nbsp;</P><H4 id="toc-hId-1036551737"><STRONG>SPTA Framework</STRONG></H4><P>The <STRONG>SPTA Framework</STRONG> provides a straightforward, function-module-based approach to simplify parallel processing with aRFCs. Instead of requiring the developer to manage the aRFC calls manually, the framework encapsulates the entire parallelization logic within a single, reusable function module, <EM>SPTA_PARA_PROCESS_START_2</EM>.</P><P>To use the SPTA framework, a developer implements three specific form routines that serve as callbacks, filling them with the custom logic required for the application. The <EM>BEFORE_RFC_CALLBACK_FORM</EM> is responsible for preparing the data and creating the work packages. The core processing logic, which is to be executed in parallel, is placed within the <EM>IN_RFC_CALLBACK_FORM</EM>. After all the parallel tasks have been completed, the <EM>AFTER_RFC_CALLBACK_FORM</EM> is called to consolidate the results and make them available for further processing.</P><P>For more information on the SPTA Framework, see these resources:</P><UL><LI><A href="https://me.sap.com/notes/3002940/E" target="_self" rel="noopener noreferrer">SAP for Me (2020): 3002940 - Parallel Processing FAQ</A></LI><LI><A href="https://sapyard.com/spta-parallel-processing-framework-in-abap" target="_self" rel="nofollow noopener noreferrer">[Non SAP] SAPYARD (2018): SPTA Parallel Processing Framework in ABAP</A></LI><LI><A href="https://www.linkedin.com/pulse/lets-talk-spta-framework-your-guide-parallel-sap-dzmitryi-kharlanau-1skaf/" target="_self" rel="nofollow noopener noreferrer">[Non SAP] LinkedIn (2024): Let’s Talk About the SPTA Framework: Your Guide to Parallel Processing in SAP</A></LI></UL><P>&nbsp;</P><H4 id="toc-hId-840038232"><STRONG>SHDB Framework</STRONG></H4><P>The <STRONG>SHDB Framework</STRONG> is a more powerful and modern, object-oriented framework that also simplifies the use of aRFCs. It is structured into four main components that work together to provide a robust parallelization environment: the <STRONG>Package Provider</STRONG>, the <STRONG>Resource Provider</STRONG>, the <STRONG>Parallelizer</STRONG>&nbsp;and the <STRONG>Dispatcher</STRONG>.</P><P>The <STRONG>Package Provider</STRONG> is responsible for automatically dividing the total dataset into smaller, processable packages according to configurable rules. The <STRONG>Resource Provider</STRONG> actively monitors the system's memory and process utilization to determine the maximum allowed number of parallel tasks, thereby preventing system overloads. The <STRONG>Parallelizer</STRONG> then calls the application-specific logic for each package in a separate aRFC task, while the <STRONG>Dispatcher</STRONG> coordinates the entire process by requesting packages and resources and launching the asynchronous tasks.</P><P>Implementation is done in an object-oriented manner, starting with the factory class <EM>CL_SHDB_PFW_FACTORY</EM> and using configuration objects from <EM>CL_SHDB_PFW_CONFIG</EM> to define parameters like the number of parallel processes or package parameters.</P><P>While a complete guide for the SHDB Framework is not publicly available at this time, some information can be found on the SAP for Me portal. Relevant resources are available there using the search terms <STRONG>"SHDB Framework"</STRONG> or <STRONG>"SHDB PFW"</STRONG>.</P><P>&nbsp;</P><H4 id="toc-hId-643524727"><STRONG>CL_ABAP_PARALLEL</STRONG></H4><P>The <STRONG>CL_ABAP_PARALLEL</STRONG> framework is another object-oriented solution for aRFC-based parallelization. Its name, while not official, comes from its original project folder. It is a lightweight solution centered around a main class and an interface that developers use to structure their parallel logic.</P><P>The implementation pattern requires the developer to create a processing class that implements the <EM>IF_ABAP_PARALLEL</EM> interface. All the custom logic intended to run in parallel is then placed within its <EM>DO</EM> method. Finally, the entire process is managed by an instance of the main <EM>CL_ABAP_PARALLEL</EM> class and the parallel execution is triggered by calling the <EM>RUN_INST</EM> method.</P><P>For more information on <STRONG>CL_ABAP_PARALLEL</STRONG>, see these resources:</P><UL><LI>Book: Schwarzmann, W. (2022): Parallel Processing with ABAP Objects: Implementation and Testing, isbn: 978-1-4932-2354-1</LI><LI><A href="https://help.sap.com/docs/btp/sap-business-technology-platform/parallel-processing" target="_self" rel="noopener noreferrer">SAP Help Portal: Parallel Processing</A></LI><LI><A href="https://community.sap.com/t5/application-development-and-automation-blog-posts/using-class-cl-abap-parallel-for-mass-parallel-dialog-work-processes/ba-p/13579844" target="_self">SAP Community (2023): Using class CL_ABAP_PARALLEL for mass parallel dialog work processes</A></LI></UL><P>&nbsp;</P><H4 id="toc-hId-447011222"><STRONG>Background Processing Framework (bgPF)</STRONG></H4><P>The <STRONG>Background Processing Framework</STRONG> serves as the dedicated framework for the <STRONG>bgRFC</STRONG> technology.</P><P>The implementation pattern requires a developer to encapsulate the business logic in a dedicated class that implements a framework interface. For most use cases, <EM>IF_BGMC_OP_SINGLE</EM> is used to ensure the process follows strict transactional rules for data consistency.</P><P>Once this class with the business logic is ready, it is passed to the <EM>CL_BGMC_PROCESS_FACTORY</EM>. This is a helper class provided by the framework that constructs the main process object for the background task. The task is then registered by calling the <EM>save_for_execution()</EM> method and the entire process is finally triggered by a <EM>COMMIT WORK</EM> statement.</P><P>For more information on the bgPF, see these resources:</P><UL><LI><A href="https://help.sap.com/docs/abap-cloud/abap-concepts/background-processing-framework" target="_self" rel="noopener noreferrer">SAP Help Protal: Background Processing Framework</A></LI><LI><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/introducing-the-background-processing-framework/ba-p/13579056" target="_self">SAP Community (2023): Introducing the Background Processing Framework</A></LI></UL><P>&nbsp;</P><H4 id="toc-hId-250497717"><STRONG>Parallel Processing Framework (PPF)</STRONG></H4><P>The <STRONG>Parallel Processing Framework</STRONG>, sometimes also referred to as the <STRONG>Framework for Parallel Processing (FPP)</STRONG>, is a framework based on background processes used to structure and execute mass-data processing runs in parallel.</P><P>Its implementation requires both settings in Customizing and the development of custom ABAP function modules. A developer first defines an <STRONG>application type</STRONG> using transaction <EM>BANK_CUS_PPC</EM>. This application type links specific processing steps, such as data packaging or execution, to the custom-developed function modules that contain the business logic.</P><P>The entire process is then initiated from a report by calling the central function module <EM>BANK_MAP_PP_START</EM>, which uses the application type's configuration to manage the parallel jobs.</P><P>For more information on the PPF, see these resources:</P><UL><LI><A href="https://community.sap.com/t5/sap-for-banking-blogs/exploring-mass-run-program-based-on-ppf/ba-p/13136452" target="_self">SAP Community (2015): Exploring Mass run program based on PPF</A></LI><LI><A href="https://help.sap.com/docs/SAP_S4HANA_ON-PREMISE/5bec6e0df6b549258e7ae381fedd4066/593e3752aeefbc02e10000000a44176d.html?locale=en-US" target="_self" rel="noopener noreferrer">SAP Help Portal: Parallel Processing (FPP)</A></LI></UL><P>&nbsp;</P><H4 id="toc-hId--443732883"><STRONG>Mass Data Framework</STRONG></H4><P>The <STRONG>Mass Data Framework</STRONG> is a comprehensive solution for structuring and controlling complex projects that involve large-scale data changes and is often used in migration scenarios.</P><P>The implementation requires just like the Parallel Processing Framework a combination of <STRONG>Customizing</STRONG> and <STRONG>development</STRONG>. In Customizing (via transaction SM30), a developer defines the entire project structure. This involves creating a <STRONG>Project Type</STRONG> (<EM>FINSV_MPROJ_TYP</EM>), which consists of a sequence of <STRONG>Activities</STRONG> (<EM>FINSV_MASSF_SET</EM>). Each activity is made up of one or more <STRONG>Steps</STRONG> (<EM>FINSV_MASSF_STEP</EM>), where the custom ABAP logic is assigned.</P><P>The developer's main task is to create an <STRONG>application class</STRONG> that contains the business logic for a step. This class must implement the interface <EM>IF_FINS_MASS_DATA</EM>, which includes three key methods. The <EM>GET_PACKAGES</EM> method is called to define the work packages. The <EM>PREPARE </EM>method can be used for any setup tasks before the parallel processing starts. Finally, the <EM>PROCESS </EM>method contains the core logic that is executed in parallel for each individual package.</P><P>As it is an older framework, further resources for the Mass Data Framework are primarily located on internal SAP platforms and are not publicly available.</P><P>&nbsp;</P><P>I hope you found this overview informative and that it helps you tackle your own performance tuning challenges.</P><P>A special thanks to <STRONG><a href="https://community.sap.com/t5/user/viewprofilepage/user-id/226501">@ManuS</a>&nbsp;</STRONG> for the help and guidance!</P> 2025-09-29T08:52:47.138000+02:00 https://community.sap.com/t5/abap-blog-posts/abap-code-to-wait-for-the-end-of-quot-inbound-bgrfc-type-q-quot-units/ba-p/14237566 ABAP code to wait for the end of "inbound bgRFC type Q" units 2025-10-07T20:28:26.490000+02:00 Sandra_Rossi https://community.sap.com/t5/user/viewprofilepage/user-id/145194 <P>I have a program which runs parallel tasks in the same system by using bgRFC and several qRFC queues: each queue runs tasks sequentially, but two queues run in parallel. With bgRFC, each task is called a unit. This scenario is called Inbound bgRFC type Q, see here for more information:&nbsp;<A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/753088fc00704d0a80e7fbd6803c8adb/48927c2caa6b17cee10000000a421937.html?locale=en-US" target="_blank" rel="noopener noreferrer">bgRFC (Background Remote Function Call) | SAP Help Portal</A>.</P><P>Once all units are started, I want the program to wait for all units to finish.</P><P>I propose a simple ABAP method which should work for most of situations.</P><P>There are really very few posts about bgRFC and the official documentation is missing information too, so I hope it can help some people. Note: I don't even know if the classes I use are supported by SAP and if it's the right way to do it, so all comments are welcome, thank you.</P><P>Here is the context how this method is used (<CODE>WAIT_END_OF_QRFC_INBOUND_UNITS</CODE>) :</P><pre class="lia-code-sample language-abap"><code>DATA(inbound_destination) = cl_bgrfc_destination_inbound=&gt;create( 'ZZZ' ). LOOP AT any_table INTO line. DATA(unit) = inbound_destination-&gt;create_qrfc_unit( ). unit-&gt;add_queue_name_inbound( line-queue_name ). CALL FUNCTION '...' IN BACKGROUND UNIT unit EXPORTING ... INSERT unit INTO TABLE units. ENDLOOP. COMMIT WORK. DATA(wait_results) = zcl_bgrfc_helper=&gt;wait_end_of_qrfc_inbound_units( i_watch_delay_seconds = 5 i_units = units ).</code></pre><P>Little explanation: there's an internal table containing data which needs to be processed in parallel via a given RFC-enabled function module. The internal table assigns given queue names to each line of data in order to achieve the parallelization. For instance, one half of the table goes to the queue named Z1, all calls in Z1 will be executed sequentially, the other half goes to the queue named Z2, the calls in Z1 and Z2 will be executed in parallel).</P><P><CODE>CALL FUNCTION ... IN BACKGROUND UNIT unit ...</CODE>&nbsp;registers a call in a given bgRFC unit. You may call several function modules in the same unit. The function modules are not called until <CODE>COMMIT WORK</CODE> is reached.</P><P><CODE>COMMIT WORK</CODE> creates the inbound bgRFC units in the database (function module calls and parameters) and all the queues are started by the bgRFC scheduler. You can see the units via the transaction SBGRFCMON.</P><P>Prerequisite: the inbound destination ZZZ was created via the transaction SBGRFCCONF. Nothing else needed (no prefix, no RFC destination in SM59, queue names are assigned freely by the program, etc.)</P><P>Here's the code of the method <CODE>WAIT_END_OF_QRFC_INBOUND_UNITS</CODE>:</P><pre class="lia-code-sample language-abap"><code>CLASS zcl_bgrfc_helper DEFINITION FINAL PUBLIC CREATE PRIVATE. PUBLIC SECTION. TYPES ty_qrfc_inbound_units TYPE STANDARD TABLE OF REF TO if_qrfc_unit_inbound WITH EMPTY KEY. TYPES: BEGIN OF ty_bgrfc_unit_state, unit TYPE REF TO if_qrfc_unit_inbound, "! Time at which the information was collected timestamp TYPE timestampl, unit_success TYPE abap_bool, unit_error TYPE abap_bool, "! In case there's a unit error unit_state TYPE bgrfc_unit_state, queue_error TYPE abap_bool, "! In case there's a queue error queue_state TYPE qrfc_queue_state, END OF ty_bgrfc_unit_state. TYPES ty_bgrfc_unit_states TYPE SORTED TABLE OF ty_bgrfc_unit_state WITH UNIQUE KEY unit. CLASS-METHODS wait_end_of_qrfc_inbound_units IMPORTING i_watch_delay_seconds TYPE numeric DEFAULT 5 i_units TYPE ty_qrfc_inbound_units RETURNING VALUE(r_bgrfc_unit_states) TYPE ty_bgrfc_unit_states. CLASS-METHODS get_timestamp RETURNING VALUE(r_result) TYPE timestampl. ENDCLASS. CLASS zcl_bgrfc_helper IMPLEMENTATION. METHOD wait_end_of_qrfc_inbound_units. TYPES: BEGIN OF ty_queue, queue_name TYPE qrfc_queue_name, dest_name TYPE bgrfc_dest_name_inbound, END OF ty_queue. TYPES tt_queue TYPE SORTED TABLE OF ty_queue WITH UNIQUE KEY queue_name dest_name. TYPES: BEGIN OF ty_unit_and_queue, unit TYPE REF TO if_qrfc_unit_inbound, queue_name TYPE qrfc_queue_name, dest_name TYPE bgrfc_dest_name_inbound, END OF ty_unit_and_queue. TYPES tt_unit_and_queue TYPE SORTED TABLE OF ty_unit_and_queue WITH UNIQUE KEY unit WITH NON-UNIQUE SORTED KEY by_inbound_queue COMPONENTS queue_name dest_name. DATA ls_unit_and_queue TYPE REF TO ty_unit_and_queue. DATA(lt_queue) = REDUCE #( INIT lt_queue_2 = VALUE tt_queue( ) FOR &lt;lv_unit&gt; IN i_units FOR &lt;lv_queue_name&gt; IN &lt;lv_unit&gt;-&gt;get_queue_names_inbound( ) NEXT lt_queue_2 = COND #( WHEN NOT line_exists( lt_queue_2[ queue_name = &lt;lv_queue_name&gt; dest_name = &lt;lv_unit&gt;-&gt;destination-&gt;dest_name ] ) THEN VALUE #( BASE lt_queue_2 ( queue_name = &lt;lv_queue_name&gt; dest_name = &lt;lv_unit&gt;-&gt;destination-&gt;dest_name ) ) ELSE lt_queue_2 ) ). DATA(lt_unit_and_queue) = VALUE tt_unit_and_queue( FOR &lt;lv_unit&gt; IN i_units FOR &lt;lv_queue_name&gt; IN &lt;lv_unit&gt;-&gt;get_queue_names_inbound( ) ( unit = &lt;lv_unit&gt; queue_name = &lt;lv_queue_name&gt; dest_name = &lt;lv_unit&gt;-&gt;destination-&gt;dest_name ) ). WHILE lt_unit_and_queue IS NOT INITIAL. WAIT UP TO i_watch_delay_seconds SECONDS. LOOP AT lt_unit_and_queue REFERENCE INTO ls_unit_and_queue. DATA(bgrfc_unit_state) = cl_qrfc_client_inbound=&gt;get_unit_state( ls_unit_and_queue-&gt;unit-&gt;unit_id ). CASE bgrfc_unit_state. WHEN if_bgrfc_client=&gt;unit_state_runnable OR if_bgrfc_client=&gt;unit_state_in_execution OR if_bgrfc_client=&gt;unit_state_blocked ##NO_HANDLER. WHEN if_bgrfc_client=&gt;unit_state_executed. r_bgrfc_unit_states = VALUE #( BASE r_bgrfc_unit_states ( unit = ls_unit_and_queue-&gt;unit timestamp = get_timestamp( ) unit_state = bgrfc_unit_state unit_success = abap_true ) ). DELETE lt_unit_and_queue USING KEY loop_key. WHEN OTHERS. r_bgrfc_unit_states = VALUE #( BASE r_bgrfc_unit_states ( unit = ls_unit_and_queue-&gt;unit timestamp = get_timestamp( ) unit_state = bgrfc_unit_state unit_error = abap_true ) ). DELETE lt_unit_and_queue USING KEY loop_key. ENDCASE. ENDLOOP. LOOP AT lt_queue REFERENCE INTO DATA(queue). DATA(bgrfc_queue_state) = cl_qrfc_client_inbound=&gt;get_queue_state( queue_name = queue-&gt;queue_name dest_name = queue-&gt;dest_name ). CASE bgrfc_queue_state. WHEN if_bgrfc_client=&gt;queue_state_runnable OR if_bgrfc_client=&gt;queue_state_in_execution OR if_bgrfc_client=&gt;queue_state_empty ##NO_HANDLER. WHEN OTHERS. LOOP AT lt_unit_and_queue REFERENCE INTO ls_unit_and_queue USING KEY by_inbound_queue WHERE queue_name = queue-&gt;queue_name AND dest_name = queue-&gt;dest_name. r_bgrfc_unit_states = VALUE #( BASE r_bgrfc_unit_states ( unit = ls_unit_and_queue-&gt;unit timestamp = get_timestamp( ) queue_state = bgrfc_queue_state queue_error = bgrfc_queue_state ) ). DELETE lt_unit_and_queue WHERE unit = ls_unit_and_queue-&gt;unit. ENDLOOP. DELETE lt_queue USING KEY loop_key. ENDCASE. ENDLOOP. ENDWHILE. ENDMETHOD. METHOD get_timestamp. GET TIME STAMP FIELD r_result. ENDMETHOD. ENDCLASS.</code></pre><P>As I said, I don't know if these classes are released by SAP:</P><UL><LI><SPAN><CODE>cl_qrfc_client_inbound=&gt;get_unit_state</CODE></SPAN></LI><LI><SPAN><CODE>cl_qrfc_client_inbound=&gt;get_queue_state</CODE></SPAN>&nbsp;</LI></UL><P>The method should support units which span other several inbound queues, but I didn't test it.</P><P>In my case, I could see that one unit has these states: runnable (briefly), in execution, executed. In a given queue, there's only one unit processed at a time. All the units instantiated after the one processed have the state blocked. Other states should be errors (e.g. short dump, uncaught exception, error message, etc.)</P><P>The queues have these states: empty if it doesn't contain any unit, runnable if it contains at least one unit to execute but it's not started yet, in execution when a unit is processed.</P><P>About the code, in case you want to ask: "DELETE itab USING KEY loop_key" is to delete the current line in the loop (LOOP AT itab), it corresponds to the old and less expressive syntax "DELETE itab". I used the pragma ##NO_HANDLER for CASE WHEN although it's not asked by the syntax check, the pragma is meant to be used for CATCH, when there's no code inside.&nbsp;</P><P>Any way, feel free to post any comment.</P><P>Thank you for reading.</P> 2025-10-07T20:28:26.490000+02:00 https://community.sap.com/t5/technology-blog-posts-by-sap/using-communication-targets-for-outbound-rfc-communication-in-abap/ba-p/14261486 Using Communication Targets for Outbound RFC Communication in ABAP 2025-11-10T04:12:55.469000+01:00 Nikolina_MH https://community.sap.com/t5/user/viewprofilepage/user-id/1952786 <P><SPAN>For those of you, who want to keep unwanted (you could even say badly dressed) destinations out of their HTTP(S) connections, check out this blog post:<BR /><A href="https://community.sap.com/t5/technology-blog-posts-by-sap/receiver-validation-http-enhance-your-security-by-controlling-destination/ba-p/13972704" target="_self">Receiver Validation HTTP - Enhance Your Security by Controlling Destination Usage</A><BR /></SPAN><SPAN><BR /></SPAN><SPAN>In the world of SAP systems, remote-enabled function modules (RFMs) are essential for connecting different systems and running functions remotely. </SPAN><SPAN>&nbsp;<BR /><BR /></SPAN><SPAN>In this article, you will be guided through the process of calling an RFM using communication targets. This ensures smooth integration between your SAP system and remote systems.</SPAN><SPAN>&nbsp;There is even a song about this phenomenon called "Smooth Integrator" . You see what we did there?&nbsp;<BR /></SPAN></P><P><STRONG>Why should you use communication targets?&nbsp;<BR /></STRONG><SPAN>Well, imagine throwing a party and accidentally inviting your ex, your accountant, and that one neighbor who always complains about your music. Nobody wants unwanted guests crashing their (SAP system) party!<BR />That's what happens when you don't have control over which applications can use which RFC destinations. It's a security and maintainability nightmare.&nbsp;&nbsp;</SPAN><SPAN><BR /></SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>You might wonder how exactly communication target get to be the "life of the party".<BR />Communication targets and application destinations provide a strong layer that simplifies complex processes. They define</SPAN><STRONG><SPAN> how</SPAN></STRONG><SPAN> your SAP system connects with external systems. For that we need to use specific configurations known as appplication destinations.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>What is an <STRONG>application destination</STRONG>, you ask? </SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>Imagine it as the ultimate party planner for your data!</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>It's the one responsible for making sure your data arrives at the right place, with the right credentials, and doesn't end up going to the wrong party. You know, like that one time you got invited&nbsp; to a LAN-Party, but&nbsp; showed up at a wild rave instead. Oops!</SPAN><SPAN>&nbsp;</SPAN></P><P><STRONG>Let's dive into the technical details.&nbsp;&nbsp;</STRONG></P><P><SPAN>When you create a communication target, you need to carefully choose which of the following settings suit you best:</SPAN><SPAN>&nbsp;<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Nikolina_MH_0-1762359295594.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/336584i082E454D8E2D2F41/image-size/medium?v=v2&amp;px=400" role="button" title="Nikolina_MH_0-1762359295594.png" alt="Nikolina_MH_0-1762359295594.png" /></span></P><UL><LI><SPAN>Enforce SAP GUI Support - it ensures application destinations allow GUIs and disallow WebSocket RFC.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Enforce Fast Serialization - mandates the use of Fast Serializer for application destinations, preventing issues by disallowing other serializers if the scenario was developed with Fast Serializer.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><UL><LI><SPAN>Default Compression Mode - allows predefined settings for higher compression in WAN scenarios or fast compression in LAN scenarios.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>When using communication targets, you can create an application destination in the transaction APPLDEST.&nbsp; This process ensures you communicate only with the intended recipients. </SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>You select your communication target and create a new application destination with a right-click:</SPAN><SPAN>&nbsp;<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Nikolina_MH_1-1762359295594.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/336585i188C55D787BF95FF/image-size/medium?v=v2&amp;px=400" role="button" title="Nikolina_MH_1-1762359295594.png" alt="Nikolina_MH_1-1762359295594.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;</SPAN></P><P><SPAN>Then you just need to name it, enter the client and select CPIC for the RFC Type.</SPAN><SPAN>&nbsp;<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Nikolina_MH_2-1762359295595.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/336586iAF8DB8E057E40079/image-size/medium?v=v2&amp;px=400" role="button" title="Nikolina_MH_2-1762359295595.png" alt="Nikolina_MH_2-1762359295595.png" /></span></P><P><SPAN>Alright, now you have an application destination. You still need to enter some important details like the host name (it can be retrieved from transaction SM51), instance and which authentication method you want to use.</SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>Application destinations are crucial component for managing external connections efficiently and securely. And now you have one too.</SPAN><SPAN>&nbsp;Good for you!<BR /></SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>If you use Cloud capabilities,&nbsp; communication targets are now available as well!</SPAN><SPAN><BR /></SPAN><SPAN>Instead of using the traditional APPLDEST transaction, the cloud environment introduces some differences regarding the application destination:</SPAN><SPAN>&nbsp;<BR /></SPAN></P><UL><LI><SPAN>In the cloud, you start by creating a communication scenario for outbound RFC, which defines the interaction between your SAP system and external systems. </SPAN></LI><LI><SPAN>A corresponding runtime configuration, including a communication arrangement and communication system, must exist for your scenario. </SPAN></LI><LI><SPAN>When a communication arrangement is saved, the system automatically creates an application destination.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><EM>But wait, there's more! </EM><SPAN><EM>&nbsp;</EM><BR /></SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>Communication targets can generally have either multiple or exactly one assigned application destination. If you're calling an RFC service via communication targets in your ABAP code, you use the CALL FUNCTION (…) IN REMOTE SESSION method, it is essential for running the function remotely. </SPAN><SPAN>It is basically like sending an RSVP to your guest, ensuring they got the invite (you get a response much faster though).&nbsp;</SPAN><SPAN><BR /></SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>When a communication target has exactly one assigned application destination, the process is straightforward. In cases where a communication target has several assigned application destinations, a few additional steps are required. </SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN>When you have several assigned application destinations, one must pass the name of the relevant application destination to the parameter </SPAN><STRONG><SPAN>application_destination</SPAN></STRONG><SPAN> when creating the communication target instance. This ensures that the correct destination is used during the remote session. Check out how easy it is: </SPAN><SPAN>&nbsp;<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Nikolina_MH_3-1762359295595.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/336588iA65ECC7143018EC0/image-size/medium?v=v2&amp;px=400" role="button" title="Nikolina_MH_3-1762359295595.png" alt="Nikolina_MH_3-1762359295595.png" /></span></P><P>&nbsp;</P><P><SPAN>&nbsp;<BR /></SPAN></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Nikolina_MH_4-1762359295595.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/336587iD5756D315B8B63AA/image-size/medium?v=v2&amp;px=400" role="button" title="Nikolina_MH_4-1762359295595.png" alt="Nikolina_MH_4-1762359295595.png" /></span></P><P><SPAN>In this example we called the function </SPAN><STRONG><SPAN>RFC_SYSTEM_INFO</SPAN></STRONG><SPAN> and we wanted to find out the maximal resources. 45 is the result.</SPAN><SPAN>&nbsp;<BR />That´s a Bingo!<BR /><BR /></SPAN></P><P><SPAN>By following alle these steps, you can call RFMs using communication targets, improving the connectivity and functionality of your SAP system.&nbsp;</SPAN><SPAN>&nbsp;</SPAN></P><P><SPAN>Just remember, the key is in the configuration.&nbsp; It should fit your specific needs, like making sure your party playlist has the right mix of songs to keep everyone dancing, and not just that one weird guy.&nbsp; We all know that one guy who just loooves to play the DJ, please don´t let him.&nbsp;<BR /></SPAN><SPAN><BR /></SPAN></P><P><SPAN>To summarize, communication targets and application destinations let you:</SPAN><SPAN>&nbsp;</SPAN></P><UL><LI><SPAN>Control which applications can crash which parties (application destinations).</SPAN><SPAN>&nbsp;</SPAN></LI><LI><SPAN>Restrict access to only those who need it.</SPAN><SPAN>&nbsp;</SPAN></LI><LI><SPAN>Avoid runtime errors and security mishaps.</SPAN><SPAN>&nbsp;</SPAN></LI></UL><P><SPAN>&nbsp;</SPAN></P><P><SPAN>In case you are not a party animal, check out the step by step guide: </SPAN><SPAN>&nbsp;<BR /></SPAN><SPAN><A href="https://help.sap.com/docs/abap-cloud/abap-integration-connectivity/calling-rfc-service-via-communication-targets?" target="_self" rel="noopener noreferrer">Calling a RFM via Communication Targets</A><BR /></SPAN></P> 2025-11-10T04:12:55.469000+01:00 https://community.sap.com/t5/technology-blog-posts-by-sap/invoking-business-agent-foundation-agents-from-abap-a-step-by-step-guide/ba-p/14274507 Invoking Business Agent Foundation Agents from ABAP: A Step-by-Step Guide 2025-11-26T10:15:43.404000+01:00 tanmay_0117 https://community.sap.com/t5/user/viewprofilepage/user-id/1527252 <P>With the rise of intelligent automation and AI-powered solutions in enterprise landscapes, integrating SAP Business Technology Platform (BTP) services with on-premise ABAP systems has become increasingly important. In this blog, I'll walk you through the process of invoking agents from the Business Agent Foundation service directly from an ABAP report—an integration that bridges the gap between traditional SAP systems and modern AI capabilities.</P><P><SPAN>Whether you're looking to enhance your business processes with intelligent agents or simply exploring the possibilities of AI integration in your SAP landscape, this guide will provide you with a comprehensive, hands-on approach to achieve this integration.</SPAN></P><P>&nbsp;</P><BLOCKQUOTE><P><STRONG>Pre-requisites</STRONG>: Subaccount in BTP, subscription of Business Agent Framework service in the subaccount, a dedicated client profile with required configurations.</P></BLOCKQUOTE><H4 id="toc-hId-2023738510">&nbsp;</H4><H4 id="toc-hId-1827225005"><STRONG>Step 1: Create Your Agent in&nbsp;Business Agent Framework</STRONG></H4><P>Setting up Business Agent Framework service in your subaccount:&nbsp;<A href="https://pages.github.tools.sap/ICN-AI-Agents/unified-agent-runtime-documentation/documentation/general/setup/" target="_blank" rel="noopener nofollow noreferrer">Setup - Project Agent Builder Documentation</A></P><P>After setting the service, go to&nbsp;<STRONG>Instances → Project Agent Builder → Service Keys → view.&nbsp;</STRONG>Copy the endpoint url (<STRONG>uaa → url</STRONG>) which is required in the OAuth 2.0 Client Profile Configuration.</P><P>Start by opening the <STRONG>Business Agent Framework</STRONG>&nbsp;application in your BTP subaccount. Create a test agent and initialize a new chat session. This agent's chat/thread will be the endpoint we'll communicate with from our ABAP system.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="tanmay_0117_0-1764151597729.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/345384i14EA867689A540D7/image-size/large?v=v2&amp;px=999" role="button" title="tanmay_0117_0-1764151597729.png" alt="tanmay_0117_0-1764151597729.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><BLOCKQUOTE><P><STRONG>Note</STRONG>: If you already have a dedicated client profile with required configurations, directly go to "Step 2: Configure the RFC Destination".</P></BLOCKQUOTE><H4 id="toc-hId-1630711500">&nbsp;</H4><H4 id="toc-hId-1434197995">OAuth 2.0 Client Profile Configuration</H4><P>Proper authentication is crucial for secure integration. Here's how to set up your OAuth 2.0 client profile:</P><H5 id="toc-hId-1366767209">Part A: Creating the OAuth Client Profile</H5><OL><LI>Navigate to transaction code <STRONG>SE80</STRONG>&nbsp;(Object Navigator)<BR /><BR /></LI><LI>Select <STRONG>Development Object</STRONG> and choose your package<BR /><BR /></LI><LI>Right-click on the package and choose: <STRONG>Create → Others → OAuth 2.0 Client Profile&nbsp;</STRONG>and enter a meaningful name for your profile<BR /><BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="tanmay_0117_2-1764062030197.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/344799i3999EB225AEE08CF/image-size/large?v=v2&amp;px=999" role="button" title="tanmay_0117_2-1764062030197.png" alt="tanmay_0117_2-1764062030197.png" /></span><BR /><P>&nbsp;</P></LI><LI>Choose <STRONG>'DEFAULT'</STRONG> as the service provider type<BR /><BR /></LI><LI>Save your profile<BR /><BR /></LI><LI>Assign the relevant scopes required for accessing the Business Agent Foundation service<BR /><BR /><BR /><BR /></LI></OL><H5 id="toc-hId-1170253704">Part B: Configuring the OAuth Client Profile</H5><OL><LI>Start transaction code <STRONG>SOAUTH2_CLIENT</STRONG>&nbsp;(or <STRONG>OA2C_CONFIG</STRONG>&nbsp;for older versions)<BR /><P>Alternatively, access it via browser:</P><PRE>&nbsp;&nbsp; https://&lt;host_name&gt;:&lt;https_port&gt;/sap/bc/webdynpro/sap/oa2c_config?sap-language=EN&amp;sap-client=&lt;client&gt;</PRE></LI><LI>Click <STRONG>Create</STRONG> and select your previously created client profile<BR /><BR /></LI><LI><STRONG>Enter Client Credentials</STRONG>:<UL><LI>Navigate to your BTP subaccount</LI><LI>Go to: <STRONG>Instances → &lt;your_service_instance&gt; → Service Keys</STRONG></LI><LI>Copy the <STRONG>Client ID</STRONG>&nbsp;from the service key and enter it in the configuration</LI></UL></LI><LI><P><STRONG>Configure Token Endpoint</STRONG>:</P><UL><LI><P>Under <STRONG>General Settings</STRONG>, enter the token endpoint URL <STRONG>without the `https://` prefix.&nbsp;<BR /></STRONG>Use the endpoint url which you copied in the Step 1.<BR /><BR /></P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="tanmay_0117_3-1764062133788.png" style="width: 940px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/344803i4592711FCEF7E7D6/image-size/large?v=v2&amp;px=999" role="button" title="tanmay_0117_3-1764062133788.png" alt="tanmay_0117_3-1764062133788.png" /></span></LI></UL></LI><LI><STRONG>Configure Grant</STRONG> <STRONG>Type</STRONG>:<UL><LI>Select <STRONG>'Client Credentials'</STRONG> as the grant type</LI><LI>This is the standard grant type for server-to-server authentication<BR /><BR /></LI></UL></LI><LI><STRONG>Verify Scopes</STRONG>:<UL><LI>The associated scopes should automatically appear if they were properly configured in Part A<BR /><BR /></LI></UL></LI><LI><STRONG>Test the configuration</STRONG>:<UL><LI>Save your configuration</LI><LI>Navigate to the <STRONG>Token</STRONG>&nbsp;tab</LI><LI>Click <STRONG>Request New Token</STRONG></LI><LI>If successful, you'll receive an access token, confirming that your OAuth configuration is working correctly<BR /><BR /><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="tanmay_0117_4-1764062168139.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/344804i0B9CDE022DCA0637/image-size/large?v=v2&amp;px=999" role="button" title="tanmay_0117_4-1764062168139.png" alt="tanmay_0117_4-1764062168139.png" /></span><P>&nbsp;</P></LI></UL></LI></OL><BLOCKQUOTE><P><STRONG>Note</STRONG>: For comprehensive details on OAuth 2.0 configuration in ABAP, refer to the official SAP documentation on [<A href="https://help.sap.com/docs/ABAP_PLATFORM_NEW/fd0fc52fd22b45f29d274a7f8236e768/cdb122d5b0784c77bf1bcce17f730e74.html" target="_blank" rel="noopener noreferrer">OAuth 2.0 Client for ABAP</A>].</P></BLOCKQUOTE><P>&nbsp;</P><H4 id="toc-hId-844657480"><STRONG>Step 2: Configure the RFC Destination</STRONG></H4><P>The destination acts as a bridge between your ABAP system and the BTP service. Here's how to set it up:</P><H5 id="toc-hId-777226694">2.1 Create the HTTP Destination</H5><OL><LI><SPAN>Navigate to transaction code </SPAN><STRONG>SM59</STRONG><SPAN>&nbsp;in your ABAP system</SPAN></LI><LI>Create a new RFC destination with the following settings:<UL><LI><STRONG>Connection Type</STRONG>: Select <STRONG>'G'</STRONG>&nbsp;(HTTP connection to external server)</LI></UL></LI></OL><H5 id="toc-hId-580713189"><STRONG>2.2 Technical Settings</STRONG></H5><OL><LI>Under the <STRONG>Technical Settings</STRONG> tab enter the host URL of your BTP service without the "<EM>https://</EM>"&nbsp;prefix<BR /><BR /><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="tanmay_0117_0-1764061796309.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/344796iF07EED4CFF84C234/image-size/large?v=v2&amp;px=999" role="button" title="tanmay_0117_0-1764061796309.png" alt="tanmay_0117_0-1764061796309.png" /></span></LI></OL><H5 id="toc-hId-384199684">2.3 Authentication Configuration</H5><OL><LI>Navigate to the <STRONG>Logon &amp; Security</STRONG>&nbsp;tab:<UL><LI>Under <STRONG>Logon Procedure</STRONG>, select <STRONG>'Logon with User'</STRONG></LI><LI>Choose <STRONG>'Basic Authentication'</STRONG> as the authentication method<BR /><BR /></LI></UL></LI><LI>Click on <STRONG>OAuth Settings</STRONG>:<UL><LI>Select your previously configured OAuth client profile (see configuration details in the OAuth Client Configuration step above)<BR /><BR /><span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="tanmay_0117_1-1764061915324.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/344797i688028F4FC0CD147/image-size/large?v=v2&amp;px=999" role="button" title="tanmay_0117_1-1764061915324.png" alt="tanmay_0117_1-1764061915324.png" /></span></LI></UL></LI></OL><H5 id="toc-hId--732516642">2.4 Test Your Connection</H5><OL><LI>Click on <STRONG>Test Connection</STRONG>&nbsp;to verify connectivity to the host URL</LI><LI>Navigate to the <STRONG>Test OAuth Configuration</STRONG>&nbsp;tab to validate the OAuth setup</LI><LI>If you encounter SSL certificate issues, use transaction code <STRONG>STRUST</STRONG>&nbsp;to upload the required SSL certificate<BR /><BR /></LI></OL><BLOCKQUOTE><P><STRONG>Note</STRONG>: For more comprehensive information on calling RESTful APIs from ABAP, refer to the [<A href="https://community.sap.com/t5/technology-blog-posts-by-members/how-to-call-restful-apis-from-sap-abap-a-step-by-step-guide/ba-p/13926663" target="_blank">Calling RESTful APIs from SAP ABAP</A>].</P></BLOCKQUOTE><H4 id="toc-hId--635627140">&nbsp;</H4><H4 id="toc-hId--832140645">Step 3: Implement the ABAP Report</H4><P>Writing the ABAP code to invoke the agent.</P><H5 id="toc-hId--1322057157">3.1 Create Your ABAP Report</H5><P class="lia-indent-padding-left-30px" style="padding-left : 30px;">Go to transaction code <STRONG>SE38</STRONG>&nbsp;and create a new report.</P><H5 id="toc-hId--1518570662">3.2 Understanding the CL_HTTP_CLIENT Class</H5><P class="lia-indent-padding-left-30px" style="padding-left : 30px;">ABAP provides a powerful class called <STRONG>CL_HTTP_CLIENT</STRONG>&nbsp;for making HTTP calls to REST APIs. This class offers two primary methods for creating HTTP client instances:</P><UL><LI>`CREATE_BY_DESTINATION` - Uses a predefined RFC destination</LI><LI>`CREATE_BY_URL` - Uses a direct URL</LI></UL><P class="lia-indent-padding-left-30px" style="padding-left : 30px;">Since we've already created our destination, we'll use `CREATE_BY_DESTINATION`.</P><H5 id="toc-hId--1715084167">3.3 The Complete Code Implementation</H5><H6 id="toc-hId-2089966617">A. Create the HTTP Client Object</H6><pre class="lia-code-sample language-abap"><code>DATA: lo_http_client TYPE REF TO if_http_client. cl_http_client=&gt;create_by_destination( EXPORTING destination = '&lt;Name of the RFC destination&gt;' IMPORTING client = lo_http_client " HTTP Client object EXCEPTIONS argument_not_found = 1 destination_not_found = 2 destination_no_authority = 3 plugin_not_active = 4 internal_error = 5 OTHERS = 6 ).</code></pre><H6 id="toc-hId-1893453112">B. Configure HTTP Method and Version</H6><pre class="lia-code-sample language-abap"><code>lo_http_client-&gt;request-&gt;set_method( if_http_request=&gt;co_request_method_post ). lo_http_client-&gt;request-&gt;set_version( if_http_request=&gt;co_protocol_version_1_1 ).</code></pre><P>We're using POST method since we're sending data to the agent, and HTTP version 1.1 for compatibility.</P><H6 id="toc-hId-1696939607">C. Set the API Endpoint</H6><pre class="lia-code-sample language-abap"><code>lv_url = '/api/v1/Agents(agent_id)/chats(chat_id)/UnifiedAiAgentService.sendMessage'. CALL METHOD cl_http_utility=&gt;set_request_uri EXPORTING request = lo_http_client-&gt;request uri = lv_url.</code></pre><BLOCKQUOTE><P><STRONG>Note</STRONG>: Replace `agent_id` and `chat_id` with your actual agent and chat identifiers from Business Agent Framework.</P></BLOCKQUOTE><H6 id="toc-hId-1500426102">D. Set Content Type</H6><pre class="lia-code-sample language-abap"><code>CALL METHOD lo_http_client-&gt;request-&gt;set_content_type( 'application/json' ).</code></pre><P class="lia-indent-padding-left-30px" style="padding-left : 30px;">Since we're sending JSON data, we specify `application/json`. If you were working with XML, you'd use `application/xml` or `text/xml` instead.</P><H6 id="toc-hId-1472096288">E. Prepare and Send the Request Body</H6><pre class="lia-code-sample language-abap"><code>lv_string = '{"msg": "give message here", "outputFormat": "Markdown", "async": false, "returnTrace": true}'. lo_http_client-&gt;request-&gt;set_cdata( lv_string ).</code></pre><H6 id="toc-hId-1275582783">F. Execute the Request</H6><pre class="lia-code-sample language-abap"><code>CALL METHOD lo_http_client-&gt;send EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2. CALL METHOD lo_http_client-&gt;receive EXCEPTIONS http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3.</code></pre><P>These two calls handle the request-response cycle.</P><H6 id="toc-hId-1079069278">G. Process the Response</H6><pre class="lia-code-sample language-abap"><code>CALL METHOD lo_http_client-&gt;response-&gt;get_status IMPORTING code = http_status reason = reason. response = lo_http_client-&gt;response-&gt;get_cdata( ).</code></pre><H6 id="toc-hId-882555773">H. Extract the Agent's Response</H6><pre class="lia-code-sample language-abap"><code>SPLIT response AT '"response":"' INTO rest response. SPLIT response AT '","' INTO explanation rest.</code></pre><P>This parsing logic extracts the actual response text from the JSON structure. The variable `explanation` now contains the agent's reply.</P><P>&nbsp;</P><P><SPAN>In conclusion, integrating SAP Business Technology Platform (BTP) services with on-premise ABAP systems is a powerful way to leverage modern AI capabilities within your traditional SAP landscape. By following the step-by-step guide provided in this blog, you can successfully invoke agents from the Business Agent Foundation service directly from an ABAP report. This integration not only enhances your business processes with intelligent automation but also demonstrates the flexibility and extensibility of SAP systems.</SPAN></P><P>&nbsp;</P><P><SPAN><span class="lia-unicode-emoji" title=":writing_hand:">✍️</span>Co-Author:</SPAN></P><P><SPAN><span class="lia-unicode-emoji" title=":bust_in_silhouette:">👤</span>‌‌<a href="https://community.sap.com/t5/user/viewprofilepage/user-id/17381">@Samruddhi</a>&nbsp;</SPAN></P> 2025-11-26T10:15:43.404000+01:00