https://raw.githubusercontent.com/ajmaradiaga/feeds/main/scmt/topics/SAP-Java-Connector-(JCo)-blog-posts.xml SAP Community - SAP Java Connector (JCo) 2024-05-20T11:13:08.216581+00:00 python-feedgen SAP Java Connector (JCo) blog posts in SAP Community https://community.sap.com/t5/technology-blogs-by-sap/sap-ui%E5%92%8Csalesforce-ui%E5%BC%80%E5%8F%91%E6%BC%AB%E8%B0%88/ba-p/13352645 SAP UI和Salesforce UI开发漫谈 2018-06-03T16:20:40+02:00 JerryWang https://community.sap.com/t5/user/viewprofilepage/user-id/165882 <UL><BR /> <LI><A class="jive-link-anchor-small" href="#sap" target="_blank" rel="nofollow noopener noreferrer">SAP UI</A><BR /> <UL><BR /> <LI><A class="jive-link-anchor-small" href="#gui" target="_blank" rel="nofollow noopener noreferrer">SAP GUI + Dynpro</A></LI><BR /> <LI><A class="jive-link-anchor-small" href="#webdynpro" target="_blank" rel="nofollow noopener noreferrer">Web Dynpro</A></LI><BR /> <LI><A class="jive-link-anchor-small" href="#webui" target="_blank" rel="nofollow noopener noreferrer">BSP/CRM WebClient UI</A></LI><BR /> <LI><A class="jive-link-anchor-small" href="#ui5" target="_blank" rel="nofollow noopener noreferrer">SAP UI5/Fiori</A></LI><BR /> <LI><A class="jive-link-anchor-small" href="#c4c" target="_blank" rel="nofollow noopener noreferrer">UI5 in SAP Cloud for Customer</A></LI><BR /> <LI><A class="jive-link-anchor-small" href="#hybris" target="_blank" rel="nofollow noopener noreferrer">Hybris Enterprise Commerce Platform</A></LI><BR /> </UL><BR /> </LI><BR /> </UL><BR /> <STRONG>Salesforce UI</STRONG><BR /> <UL class="list-paddingleft-2"><BR /> <LI><STRONG>Apex</STRONG></LI><BR /> <LI><STRONG>Lightning Experience</STRONG></LI><BR /> <LI><STRONG>Aura Framework</STRONG></LI><BR /> <LI><STRONG>Lightning Component Framework</STRONG></LI><BR /> <LI><STRONG>Visualforce</STRONG></LI><BR /> </UL><BR /> <H1 id="sap" id="toc-hId-775710282"><STRONG>SAP UI</STRONG></H1><BR /> <H2 id="gui" id="toc-hId-708279496"><STRONG style="font-size: 1rem">SAP GUI + Dynpro</STRONG></H2><BR /> 用SAP GUI + Dynpro 开发应用的UI界面仿佛是石器时代的事情了。据我所知,至少在SAP成都研究院已经没有团队仍旧使用这种古老的技术来开发UI了。虽然S/4HANA的后台还有大量事务码可供终端用户使用,但是,借助SAP Internet Transaction Server(ITS),这些基于SAP GUI的事务码可以直接运行在浏览器端,并且具有Fiori应用的外观。<BR /> <BR /> 也就是说,如果您的S/4HANA On Premise客户需要一些新的UI, &nbsp;除了常规的UI5开发方式之外,从技术上说,您完全可以仍然用SAP GUI开发一个Dynpro Screen, 然后封装成一个事务码,最后把这个事务码分配到S/4HANA Fiori launchpad的某个tile上。具体做法可以参考我的博客:<A href="https://blogs.sap.com/2016/12/21/open-your-sap-gui-transaction-in-fiori-launchpad/" target="_blank" rel="noopener noreferrer">Open your SAP GUI transaction in Fiori launchpad</A><BR /> <BR /> 用浏览器访问SAP GUI 事务码SE80的效果如下:<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf8ECRCpV2DsDtNXWcqbhH0rtaWwOvwKpQSbAWNJlaDcWpcv3YdQsC1w/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 实际上,S/4HANA的很多标准应用也采用了这种做法。以物料主数据管理应用为例,S/4HANA既存在采用这种“障眼法”打造而成的伪Fiori应用(下图标注了事务码的3个tile),也存在下文要介绍的根正苗红的原生Fiori应用(下图蓝色tile所示)。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfm6s7cA4hu45PAgdIxYOonpYwGQz43gpHtWuqcwMtBGjO7SDKxkMV7g/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <H2 id="webdynpro" id="toc-hId-511765991"><STRONG>Web Dynpro</STRONG></H2><BR /> 从实现语言上分为ABAP Web Dynpro和Java Web Dynpro。据我所知基于ABAP Web Dynpro开发的SAP标准应用比Java Web Dynpro多得多, 比如SAP SRM的标准UI就基于ABAP Web Dynpro。另外有很多属于SAP_BASIS software component的应用或框架,其UI也是使用ABAP Web Dynpro开发的,最著名的莫过于BRF(Business Rule Framework) 。<BR /> <BR /> 作为Netweaver ABAP栈的一部分,BRF和其升级版BRF+在SAP许多产品里都发挥了重要作用。典型的例子有SAP Solution Manager的Incident Management和SAP Cloud for Customer的Service Request应用场景里的Support Team Determination功能。通过BRF我们可以配置一系列规则(rule),这些规则基于Incident的component,system id, client id和priority等字段。BRF能够根据用户配置的这些规则,自动决定出哪个团队应该处理该Incident / Service Request。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfrvFXG21m2PqHicbaKiaDpHl1S22OMYsuZGOBaCSRHViaIszMJvKuicJ0pg/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 再有就是SAP Document Builder,一款复杂文档生成的解决方案。文档管理员负责配置符合实际业务中使用文档外观及格式的文档元素(element), 这些通过Word编辑的文档元素是最终生成文档的组成部分。用户访问ABAP Web Dynpro UI,填写一些关键字段,最后一键生成PDF,Word,HTML或者XML格式的文档。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfEZRTGwrtDgsGSaJVVBjjbYNx9KXIVB3o7FibPx4FTNHVTNZA0GibEOmg/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 该技术尤其适用于部分国内客户,这些客户认为SAP标准UI导出而成的文档格式和客户平日使用的纸质文档(比如销售合同)的外观相去甚远。通过Document Builder,客户可以用Word设计符合自己格式和外观要求的文档元素作为模板然后上传到系统里,基于这些模板生成最终文档。<BR /> <BR /> SAP Document Builder的ABAP Web Dynpro UI:<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfO8q17ICwDw4fS03IWXSEtoldraXjM4ut7dBicJRnJhbSA0ZI3zCrlhQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 此外,ABAP Web Dynpro上手快,学习曲线相对平缓,具有接近所见即所得的UI编辑方式。作为一个MVC框架,ABAP Web Dynpro不需要像CRM WebClient UI那样必须开发一个真正意义上的Business Object(以下简称为BO)作为模型,而是可以直接在controller里面调用底层API。这种简单快捷的开发方式深受Partner的欢迎。在我支持过的每一个On Premise项目的二次开发里几乎都能看到ABAP Web Dynpro的身影。<BR /> <BR /> 尽管ABAP Web Dynpro有这么多优点,但并不意味着它是一个万能的解决方案。因为无法很好的适配移动设备,在Fiori诞生之后,ABAP Web Dynpro逐渐退出UI开发的历史舞台了。<BR /> <BR /> 需要提醒的一点:<BR /> <BR /> 如果一个SAP标准产品的UI不是使用ABAP Web Dynpro开发的,那么在您决定使用这个技术进行二次开发之前,请慎重考虑,因为您很可能会遇到这些坑:<BR /> <UL class="list-paddingleft-2"><BR /> <LI>后退按钮的处理</LI><BR /> <LI>数据丢失的检测和处理</LI><BR /> <LI>会话处理</LI><BR /> <LI>对UI可配置性(configurability)的支持</LI><BR /> <LI>消息显示区域的处理</LI><BR /> <LI>对底层API不恰当的调用</LI><BR /> </UL><BR /> 这些坑都是我以前支持国内客户项目时,发现大量ABAP Web Dynpro和CRM WebClient混合使用造成的。关于这些坑的更多细节,请参考我的博客: <A href="https://blogs.sap.com/2014/01/08/issue-lists-of-using-abap-webdynpro-in-crm-ui" target="_blank" rel="noopener noreferrer">Issue lists of using ABAP Webdynpro in CRM UI</A>.<BR /> <H2 id="webui" id="toc-hId-315252486"><STRONG>BSP/CRM WebClient UI</STRONG></H2><BR /> SAP BSP是一项神奇而重要的技术。神奇,是因为它历史实在太悠久了,据我所知从上世纪90年代年起一直服役至今。而它重要的一面,暂时卖个关子。<BR /> <BR /> BSP和JSP的原理一致,能直接在前端HTML页面里通过&lt;%和%&gt;嵌入ABAP代码。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfm6DO5fFvJTYOzt4Hdo1qHsPue7qzKQsk1dTyR1M7PwQUicymcQDSPuw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 运行时这些ABAP代码在服务器端执行,然后被合并到页面源代码中去,最后服务器端将页面源代码发送给浏览器,显示给用户。<BR /> <BR /> 下图是一个BSP应用的例子。BSP的HTML里仍然能触发一些事件,但是这些事件的响应函数不是JavaScript函数,而是由ABAP实现的代码片段,即下图左边的On开头的一系列事件处理逻辑。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfm7u9qFEHAtccBZICc8Bfmhc8vnIc4EJ0GdVw7EUGSicjTiaSOYAC2FXA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfBu6A1u2IJGAHrqlMNYDOyhiavib7ibPabRmCHZ4PVicL84SE1K3gricnxpw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 从上面的界面也能看出,BSP应用缺乏MVC支持,并且仅能在其框架支持的6个事件响应位置进行ABAP编程。用BSP开发一些小工具还行,如果拿来开发企业级应用则显得有些力不从心。正因为BSP的这个缺陷, CRM WebClient UI 才有了用武之地。<BR /> <BR /> CRM WebClient UI应用本质上也是一个BSP应用,同传统的BSP开发事务码SE80不同,CRM WebClient UI有一个新的开发事务码,该开发工具提供了使用BO作为MVC中模型层的原生支持,即开发人员可以在开发工具里将BO某个字段绑定到UI某个字段上。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf4C1MTUkg6jPbzre5TVuGHQwXX0OI3ibAe7NzcNTtL7VXkOyicNx2vmHg/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> WebClient UI和下面将要介绍的SAP UI5一样,也包含了很多开箱即用的标准控件,只不过我们一般不用控件这个术语,而称为元素(Element)。应用开发人员只需要使用这些标准元素,就能快速开发出高质量的UI界面。<BR /> <BR /> 举个例子,下图是一个典型的使用WebClient UI实现的搜索页面,第2行和第3行声明了SAP标准元素库thtmlb和chtmlb的引用,然后在第11行使用了thtmlb库里的元素searchFrame。有SAP UI5开发经验的朋友可以把这种做法类别成在UI5的XML view里使用SAP标准的UI5控件,原理是相同的。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf0b9qkMO06TACKCibA6QZlJ0COV72uFCaDGI2OIQeOIEXGhxNjNDDqgQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 短短29行代码,就绘制出了如下图的搜索界面:不仅支持通过下拉菜单更换搜索条件,也支持通过带有+和-的圆形按钮添加或者删除搜索条件。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfz6rXDltLQGUU2LWB7YjHwAPk7iaPGPUpprrsD3qtRyRNME2tL1JSb3w/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 如此一来,应用程序开发人员无需再去编写原生的HTML代码和CSS。在运行时期,searchFrame元素对应的Render类会负责生成原生的HTML代码。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf6uYhq3de86Q6BfnVTvHQybZTMxAxDDmD7PlBxe7QibMjeKbr9XmDuaA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 关于WebClient UI更多开发细节,请参考我的公众号文章<A href="http://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247483888&amp;idx=1&amp;sn=b94638f2be620423e2001943f4211783&amp;chksm=ead5b367dda23a713af3fb13bda2334c715a8fc2a65222a9f8d3a6f8e8ee8a887196e05a5f2e&amp;scene=21#wechat_redirect" target="_blank" rel="noopener nofollow noreferrer">Jerry的WebClient UI 42篇原创文章合集</A>。<BR /> <BR /> 此外,CRM WebClient UI和ABAP Webdynpro相比,多了下图中红色方框所示的Business Object Layer和Generic Interaction Layer,有的朋友可能认为这两层会带来一些额外的运行时开销(runtime overhead),导致WebClient UI的性能不如ABAP Web Dynpro。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfOSlxlm7d8qfN9VXiakeyuHHSyoIsl9jJAiaFuH0U7kKXEVONZhUsrUAQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 关于这个运行时额外开销的话题,我曾经做过评测,结果证明:假设用WebClient UI和ABAP Web Dynpro实现同样的需求,WebClient UI引入BOL和GenIL层带来的运行时开销并不会导致其性能比ABAP Web Dynpro相差太多。底层API逻辑越复杂,这个运行时开销越可以忽略不计。<BR /> <BR /> 下图就是我分别使用Social Post,Sales Order和Product三个应用测试出来的BOL和GenIL造成的运行时开销明细。关于我做的这个性能评测的更多细节,请参考我的博客<BR /> <BR /> <A href="https://blogs.sap.com/2014/01/02/webclient-ui-vs-abap-webdynpro-performance-loss-in-bol-genil-layer-discussion/" target="_blank" rel="noopener noreferrer">Webclient UI vs ABAP webdynpro: performance loss in BOL / Genil Layer discussion</A><BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfweia3vTvBFWGYicaGtRGiaW4dAFSibhksJ0icD1Jd5FKkwxicAGa8kNRBc4A/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfanrl2ibzHaWxibhfSicy6LzC3ibQqfQG8tDPnwAuC3FGjP3tLYicLiakqbGw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <H2 id="ui5" id="toc-hId-118738981"><STRONG>SAP UI5/Fiori</STRONG></H2><BR /> 这对术语经常伴随着彼此同时出现,有的朋友对二者的区别和联系搞得不是太清楚。Fiori是SAP官方的设计语言,代表一种UI的设计风格,我的同事周帅在他的微信文章&nbsp;<A href="http://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484260&amp;idx=1&amp;sn=534aca2616d51f9262d38f2c845a6b99&amp;chksm=ead5b1f3dda238e559405b224b56a6c60277c5d4df38720d2cd3104227a4633485af57d836f8&amp;scene=21#wechat_redirect" target="_blank" rel="noopener nofollow noreferrer">SAP成都C4C小李探花:浅谈Fiori Design Guidelines</A>&nbsp;里对SAP Fiori有着详细介绍。而SAP UI5是一种UI开发技术, 一个基于jQuery的UI开发框架和UI控件库。<BR /> <BR /> 目前S/4HANA, SAP Cloud for Customer, SAP Engagement Center, SAP Revenue Cloud这些产品的UI都基于SAP UI5。<BR /> <BR /> 为什么我前面介绍BSP时说这项技术如此重要呢?SAP的旗舰产品S/4HANA, 其Fiori应用仍是以BSP的方式存储在Netweaver上。<BR /> <BR /> 比如S/4HANA物料主数据管理的Fiori应用,其BSP应用名称:md_prod_mas_s1<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf6GnI4kdCEfibsVPohria5oXExD3ZDb7lH7iciauXVS6c4uDzWNeBx6hGUg/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 该BSP应用在ABAP后台打开如下所示:<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfUPwKhoFCxT50WoDyDXLYZiconIicjiakbZr06dpJHbKxe1ibW1yN01xmQw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 开发人员可以用WebIDE, Eclipse, Webstorm,Atom, Sublime Text或任何喜欢的其他IDE/编辑器进行SAP UI5开发。开发完成后,这些UI5应用一旦部署到Netweaver,SAP框架会自动创建一个BSP应用,存储该UI5应用的全部内容。关于更多Fiori应用的部署细节,请参考我的公众号文章&nbsp;<A href="http://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247483825&amp;idx=1&amp;sn=3a4c175890e85df88236273763e06550&amp;chksm=ead5b326dda23a30e20b192eeb1fe9838c900a05769a68dfe9aebf628424becc3190e402f363&amp;scene=21#wechat_redirect" target="_blank" rel="noopener nofollow noreferrer">SAP Fiori应用的三种部署方式</A>。<BR /> <BR /> SAP UI5支持不同的view类型,最常用的是xml view和js view。对于xml view,在里面声明要使用哪些UI5控件。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf9ZqAoGL3pF3UVPga0qOx0ID8MeGqWHIibHLZWc1bfbkArvOrapD5mzA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 在运行时,xml view被加载,内容被UI5框架的XMLTemplateProcessor解析成一颗DOM树,树上的每个叶节点对应xml view中一个UI5控件的声明。然后深度遍历这颗树,创建UI5控件运行时实例。因为是深度遍历,所以您能在下图调用栈里观察到很多handleChildren和createRegularControls的递归调用。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfvyVB1u3aNoHte5E0CiaPeWFZozh5JwCNCuYjHJkZVhSicdpibvf7egIiaQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 同xml view相比,js view里控件的实例化不是由XMLTemplateProcessor完成,而是开发人员在JavaScript代码里自行实现。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf9xic8bCMGZicgPEADoZE9EwsS1o9ooqANYiae5jfNLsfUORUvEKMWVrBQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 每个UI5控件都有一个对应的渲染器(renderer), 负责在运行时根据实例包含的各项属性渲染出对应的HTML原生代码。<BR /> <BR /> 然而有的S/4HANA Fiori应用,如果您按照我这篇文章&nbsp;<A href="http://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484306&amp;idx=1&amp;sn=314d749da91a94064ef1e258657a0974&amp;chksm=ead5b105dda23813addbca28689e3fcc22c0b47cb2d4f49557ec796edfa8fe88c43d2c70567a&amp;scene=21#wechat_redirect" target="_blank" rel="noopener nofollow noreferrer">Jerry和您聊聊Chrome开发者工具</A>&nbsp;介绍的方法,用Chrome开发者工具打开它的实现,会发现这个应用既没有xml view,也没有js和其他类型的view。那么,我们看到的Fiori UI到底是怎么画出来的呢?<BR /> <BR /> 举个例子,如果您按照我这篇博客的步骤,您可以在几分钟内,构造出一个支持Service Order增删改查的Fiori应用出来,并且不需要写一行JavaScript代码。<BR /> <BR /> <A href="https://blogs.sap.com/2016/03/31/create-a-crm-service-order-fiori-application-within-a-couple-of-minutes/" target="_blank" rel="noopener noreferrer">Create a CRM Service Order Fiori application within a couple of minutes</A><BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jfkM75AAibb6jkB4A8ZSbmoWZjkTuNecnl5Pkx8ibhhpF8kpART6g3Y8Zw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 奥妙就在于这里使用了一个叫做Smart Template的Fiori框架。使用这个框架,界面布局信息不再维护于xml或者js view里,而是定义在CDS view内。<BR /> <BR /> 下图是我博客里提到的Service Order应用使用到的某个CDS view在ABAP Studio里的显示。可以观察到有很多annotation(注解), 其中名称以@UI开头的注解定义了一些元数据,描述了被注解的字段出现在Fiori UI上的具体位置。<BR /> <BR /> @UI.lineItem: 以一个column的外观出现在UI的搜索结果列表里,具体位置通过属性position指定。<BR /> <BR /> @UI.selectionField: 声明该字段渲染成搜索字段。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jficHGXicW55vunicZkBpM9JbpOvbo6Iju62Lwq7QEl3jAJ8wdfoqbRdD0Q/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 这些注解的详细定义在SAP help上能找到。这就是元数据驱动(metadata-drive development)的UI开发方式。这种方式实际将UI开发的大部分复杂度从应用开发人员身上转嫁到了Smart Template框架实现本身。使用这个框架,应用开发人员所需要做的就是专注于CDS view的开发,以及在view里定义UI注解。在运行时,由SAP UI5框架将这些元数据读取出来,然后负责生成原生的HTML代码。<BR /> <BR /> 这解释了为什么您在基于Smart Template的Fiori应用里找不到xml或者js view,因为UI布局压根就不再存储于这些前台资源里,而是维护在ABAP后台的CDS view里。<BR /> <BR /> 下图是之前提到的Service Order Fiori应用使用到的CDS view的层级结构。每个view的详细代码在我的博客里。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4iadRs1KNEHtFTYpAxyq2jf6libaEkpo4PLNnPWDzevc79yQIaBeQOMzmHSIO1VsvEic6EEsY5f4xpA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 关于Smart Template的更多介绍,请参考我的公众号文章&nbsp;<A href="http://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247483680&amp;idx=1&amp;sn=bbca83f9ce449e439dbd45f948a0ba2e&amp;chksm=ead5b3b7dda23aa15e3d30d6867fcdc5df83d130e22dda5060507ec65d971e3cb173c16235af&amp;scene=21#wechat_redirect" target="_blank" rel="noopener nofollow noreferrer">Jerry的通过CDS view + Smart Template 开发Fiori应用的blog合集</A>&nbsp;。<BR /> <H2 id="c4c" id="toc-hId--77774524"><STRONG>UI5 In SAP Cloud for Customer(C4C)</STRONG></H2><BR /> 之所以要把C4C单独拿出来讲,是因为虽然C4C也基于SAP UI5,但是对SAP UI5的使用方式和SAP其他产品,如S/4HANA, SAP Revenue Cloud, SAP Engagement Center相比还有所不同。SAP成都研究院C4C开发团队的Yang Joey在他的微信公众号文章有详细的介绍:<BR /> <BR /> <A href="https://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484704&amp;idx=1&amp;sn=20f898617ce51a28749ef89db5e01cf9&amp;chksm=ead5b7b7dda23ea11c5a2d4d7ff2fd89295de088438af4396a3d55dc7402ab902c2fc8eeb129#rd" target="_blank" rel="nofollow noopener noreferrer">SAP成都研究院C4C光明左使:SAP Cloud for Customer 使用SAP UI5的独特之处</A><BR /> <H2 id="hybris" id="toc-hId--274288029"><STRONG>Hybris Enterprise Commerce Platform(ECP)</STRONG></H2><BR /> 按照使用场景可分为Storefront UI(前台电商页面)和Backoffice UI(后台管理页面)。<BR /> <BR /> Storefront UI布局和使用方式均和我们每天用的淘宝京东等类似,采用JSP开发。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWeGuGjyjpCF7Llib6mxOheR9qq9PQuaaexI4sEkHSEaHiaJic88Nv2jhpQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 同前文介绍的CRM WebClient UI使用的BSP技术一样,在Hybris Storefront UI的JSP开发中,Hybris也封装了很多标准的UI元素供开发人员使用。在Hybris里把这些标准UI元素称为Tag(标签)。<BR /> <BR /> 比如下图使用标签ycommerce:testId来分页显示产品搜索结果:<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWeM1BceOIdtyeAxMH1yX2FrDxmq066bKuZiaHVmiamfZjV6uJoTa5BKWA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 这个标签的定义位于文件:<BR /> <BR /> ext-template/yacceleratirstorefront/web/webroot/WEB-INF/common/tld/ycommercetags.tld<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWyNGJgjCYEaBcBnRS0aLEkvTtYNsYJdVbkzqF99oSYNUibUEXmayvia4g/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 而标签的实现位于文件TestIdTag.java:<BR /> <BR /> ext-template\yacceleratorstorefront\web\src\de\hybris\platform\yacceleratorstorefront\tags<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWV8C5icnick3Sz5wicpgmEpe1SImdqnRXUO3rgI4ricG9vicnicDjkYrejzqg/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 同前面讲过的UI5控件的Renderer,WebClient UI元素的Renderer职责相同,该Java类也能看作是JSP标签的Renderer,负责在运行时渲染JSP tag&nbsp;testId 对应的原生HTML代码。<BR /> <BR /> 上图注释还提到,为了确保id唯一,pageContext内部维护一个计数器,每次生成页面元素后计数器加1。该计数器产生的整数值作为最后生成原生HTML div标签id属性的后缀,确保每个div标签有全局唯一的id。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWaz7o3uYBpibRTaP5NjU7q5m0B1zrg8R2dlAKGpuNPibC8tArcn5aB4sw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 而Hybris JSP标签这套确保div id属性全局唯一的实现方式,和WebClient UI竟完全一致。从下图一个WebClient UI页面的原生HTML代码中我们能轻易发现id属性值的整型后缀:<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWV0NeVC3E7LUIr6vNmgibUs7wTEjmJrbOvnp1HoadicicAgJQSdqhoWOiaA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> WebClient UI里id属性计数器的累加在下图第24行完成。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWRVoB8uFlCMvVKPsqCzDyy8eGuGPdrEPcJ4rHrYSxJzeGOz2icA1pmuQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 关于Hybris JSP标签的更多细节,请查看我的博客:<BR /> <BR /> <A href="https://blogs.sap.com/2018/02/02/jsp-attribute-tag-used-in-hybris-ui-implementation-and-counterpart-in-abap-bsp/" target="_blank" rel="noopener noreferrer">JSP attribute tag used in Hybris UI implementation and counterpart in ABAP BSP</A><BR /> <BR /> 以上仅仅是Hybris ECP storefront UI开发微观层面的描述。从宏观上来讲,这些JSP开发而成的界面如何组装起来最后形成用户看到的电商页面呢?类似SAP WebClient UI的Navigation Profile可以基于业务角色(Business Role)定义一系列UI以及其页面跳转关系,Hybris ECP也有类似的模块称为Web Content Management System(WCMS):<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWfJOu9GZrBiahdqPMMRQQFWUq3ib7OdFZJQv6P9sT2Qush4B0HmI9Ap5A/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 在WCMS里可以定义一个页面的模板(Template), 模板里包含了不同的Page Slot,这些Slot里放置具体的UI Component。比如下图的homepage模板,定义了电商首页的布局,我们能观察到SiteLogoSlot位于TopHeaderSlot和ButtonHeaderSlot之间,包含了SiteLogoComponent,后者负责在电商页面上显示logo。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyW3uo9kLW3OF5iauhoXjoIylooHY2qExsD3I9YUq4BHWmiaiaPfdQVtianPA/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 而UI component tag的渲染,分为渲染前,渲染中和渲染后三个阶段,分别对应renderItem方法中的三个子方法:<BR /> <UL class="list-paddingleft-2"><BR /> <LI>beforeItem</LI><BR /> <LI>renderItem</LI><BR /> <LI>afterItem</LI><BR /> </UL><BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4wfIKSGdib23X8CKQNKvAv8yTkxwf1daVe9r9Qe2VK0Y1SFPTOicHCBahDlmQDOPW5RZkYtWcstaFw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 这三个方法分别对应了WebClient UI中的这三个子方法:<BR /> <UL class="list-paddingleft-2"><BR /> <LI>DO_AT_BEGINNING</LI><BR /> <LI>RENDER</LI><BR /> <LI>DO_AT_END</LI><BR /> </UL><BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y4wfIKSGdib23X8CKQNKvAv8U2wUOuTqxXfZyqu9RIZ6fJ4iboX6xX4IMQtnkA32vxUgu2paGSKQCeQ/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> 至于通过WCMS创建的template在运行时如何生成最终的HTML源代码,则是一个比较复杂的过程,这里限于篇幅不做详细介绍,大家可以参考Hybris官网上的帮助文档。<BR /> <BR /> <IMG class="" src="https://mmbiz.qpic.cn/mmbiz_png/AMo67hTS6Y6g2dgQUYDft78gpefCtwyWmyK5TAuQs6AvseAia1QxOe9xm1NMF9F96MBH9MwlLREvibnwQKlc0hicw/640?wx_fmt=png&amp;tp=webp&amp;wxfrom=5&amp;wx_lazy=1" /><BR /> <BR /> <STRONG>Salesforce UI</STRONG><BR /> <BR /> 谈起Salesforce UI,会遇到以下一些名词:<BR /> <UL class="list-paddingleft-2"><BR /> <LI>Apex</LI><BR /> <LI>Lightning Experience</LI><BR /> <LI>Aura Framework</LI><BR /> <LI>Lightning Component Framework</LI><BR /> <LI>Visualforce</LI><BR /> </UL><BR /> &nbsp;<BR /> <BR /> Jerry处于兴趣也在业余时间对这些概念做了粗浅的研究,详情可以参考我这篇<A href="https://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484460&amp;idx=1&amp;sn=aafe62ded3bc7b07f4d3da99f3926ab3&amp;chksm=ead5b6bbdda23fad3c4b7e8148d61e4c9a2609f13151a221da1bf313a25f0df37fab8d9ec557#rd" target="_blank" rel="nofollow noopener noreferrer">微信公众号文章</A>。 2018-06-03T16:20:40+02:00 https://community.sap.com/t5/technology-blogs-by-sap/%E7%94%A8javascript%E8%AE%BF%E9%97%AEsap%E4%BA%91%E5%B9%B3%E5%8F%B0%E4%B8%8A%E7%9A%84%E6%9C%8D%E5%8A%A1%E9%81%87%E5%88%B0%E8%B7%A8%E5%9F%9F%E9%97%AE%E9%A2%98%E8%AF%A5%E6%80%8E%E4%B9%88%E5%8A%9E/ba-p/13354925 用JavaScript访问SAP云平台上的服务遇到跨域问题该怎么办 2018-06-06T06:11:14+02:00 JerryWang https://community.sap.com/t5/user/viewprofilepage/user-id/165882 <UL><BR /> <LI><A class="jive-link-anchor-small" href="#cors" target="_blank" rel="nofollow noopener noreferrer">解法1:Cross-Origin Resource Sharing</A><BR /> </LI><BR /> <LI><A class="jive-link-anchor-small" href="#jsonp" target="_blank" rel="nofollow noopener noreferrer">解法2:JSONP</A></LI><BR /> <LI><A class="jive-link-anchor-small" href="#proxy" target="_blank" rel="nofollow noopener noreferrer">解法3:自开发ProxyServlet</A></LI><BR /> <LI><A class="jive-link-anchor-small" href="#further" target="_blank" rel="nofollow noopener noreferrer">更多阅读</A></LI><BR /> </UL><BR /> <BR /> 关于JavaScript的跨域问题(Cross Domain)的讨论, 网上有太多的资源了。国内的程序猿写了非常多的优秀文章,Jerry这里就不再重复了。<BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/01-wechat.png" /><BR /> 直入主题,最近我正在做一个原型开发:通过SAP云平台和SAP Cloud Connector把On-Premise系统上的ABAP function module STFC_CONNECTION 暴露出来,给微信消费。<BR /> 这个function module的逻辑很简单,直接把输入参数REQUTEXT的内容不加任何处理,拷贝到输出参数ECHOTEXT。<BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/02-gui.png" /><BR /> 具体操作步骤参考我的公众号文章:<A href="https://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484533&amp;idx=1&amp;sn=57587494ffa36fda4cd97afc3cb08716&amp;chksm=ead5b6e2dda23ff4f9b3c6623aa381c3620e7e349c210bda0516291463de487846d89cc97e22#rd" target="_blank" rel="nofollow noopener noreferrer">使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数</A><BR /> 部署到SAP云平台后,通过如下的API endpoint进行调用:<BR /> <A href="https://demoi042416trial.hanatrial.ondemand.com/connectivity/api?userinput=" target="test_blank" rel="nofollow noopener noreferrer">https://demoi042416trial.hanatrial.ondemand.com/connectivity/api?userinput=</A><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/03-chrome.png" /><BR /> 然后在我的微信消息服务器上发起如下的AJAX调用去消费(因为是POC,所以把API endpoint硬编码在第3行):<BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/04-ajax.png" /><BR /> 遇到了意料之中的跨域错误: No 'Access-Control-Allow-Origin' header is present on the requested resource.<BR /> <BR /> 如何解决?<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/05-error.png" /><BR /> <H1 id="cors" id="toc-hId-775772685">解法1:Cross-Origin Resource Sharing</H1><BR /> 如果服务器端的响应能够通过编程或配置去影响,那么可以借助Cross-Origin Resource Sharing,在HTTP响应结构中添加字段Access-Control-Allow-Origin,其内容根据实际业务赋以需要的origin字段即可。这里的origin在Jerry看来就是一个白名单。<BR /> 解决方案参考我的博客:<BR /> <A href="https://blogs.sap.com/2017/05/06/cross-domain-request-in-abap-and-java-with-two-workaround/" target="_blank" rel="noopener noreferrer">Cross domain request in ABAP and Java</A><BR /> <H1 id="jsonp" id="toc-hId-579259180">解法2:JSONP</H1><BR /> 用JSONP也能解决跨域问题,但这个方法同样需要在服务器端通过编程方式做一些处理。具体使用方式参考我的博客:<BR /> <A href="https://blogs.sap.com/2017/06/04/play-around-with-jsonp-in-nodejs-server-and-abap-server/" target="_blank" rel="noopener noreferrer">Play around with JSONP in nodeJS server and ABAP server</A><BR /> <BR /> 而我使用SAP云平台加上Cloud Connector将On Premise上的function module暴露到公网,这种方式开发人员无法对HTTP的响应头进行编程或配置。因此JSONP对于我原型开发解决跨域问题也没有帮助。<BR /> 在SAP云平台的Mobile Service for Development and Operations cockpit里有对应的Cross Domain Access参数配置。不过我的原型开发没有用到SAP云平台Mobile Service这套架构,因此也不适用。<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/06-mobile.png" /><BR /> <H1 id="proxy" id="toc-hId-382745675">解法3:自开发ProxyServlet</H1><BR /> 接下来咋办?Jerry以前做CRM Fiori开发时,用的是Eclipse IDE,在本地起一个Tomcat,上面跑的Fiori应用也能通过localhost这个域访问到On-Premise系统域上的OData服务。当时咋不会遇到跨域问题呢?仔细回忆了一下,当时我们的Tomcat服务器上还部署了一个Proxy Servlet。Index.html发送的AJAX请求被ProxyServlet拦截,由ProxyServlet通过Java代码向On-Premise系统发起请求。请求得到响应之后,ProxyServlet再将其发送给Index.html。<BR /> 这种类型的Servlet其原理在我的这篇博客里有详细介绍:<BR /> <A href="https://blogs.sap.com/2014/12/04/explore-the-comsapui5resourceresourceservlet/" target="_blank" rel="noopener noreferrer">Explore the com.sap.ui5.resource.ResourceServlet</A><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/07-proxy.png" /><BR /> 思路清楚后,写代码实现就很容易了。上图对应的Java Web项目的源代码在我的<A href="https://github.com/i042416/SCPCrossDomainSolution" target="_blank" rel="nofollow noopener noreferrer">github</A>上:<BR /> <BR /> 1. index.html里发送的AJAX请求实际指向的处理者是ProxyServlet:注意下图第三行的请求url路径中的proxy。<BR /> <BR /> 2. 开发一个ProxyServlet,拦截url路径里包含proxy的那些请求。回到我的原型开发需求,SAP云平台上的API消费如今通过ProxyServlet来实现,为简单起见,我将API endpoint硬编码在ProxyServlet里。<BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/09-servlet.png" /><BR /> 经过测试,能按照期望的方式工作:域localhost的AJAX请求能够成功访问SAP云平台上的API:<BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/10-ok.png" /><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2018/06/11-ok.png" /><BR /> 写完之后我在Google上搜了一下,发现SAP已经在github上发布了一个标准的<A href="https://github.com/SAP/cloud-connectivityproxy" target="_blank" rel="nofollow noopener noreferrer">Proxy project</A>,用于处理这种JavaScript跨域访问的问题,大家有兴趣可以了解一下:<BR /> <H1 id="further" id="toc-hId-186232170">更多阅读</H1><BR /> ● <A href="https://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484533&amp;idx=1&amp;sn=57587494ffa36fda4cd97afc3cb08716&amp;chksm=ead5b6e2dda23ff4f9b3c6623aa381c3620e7e349c210bda0516291463de487846d89cc97e22#rd" target="_blank" rel="nofollow noopener noreferrer">使用Java + SAP云平台 + SAP Cloud Connector调用ABAP On-Premise系统里的函数</A><BR /> ● <A href="https://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484555&amp;idx=1&amp;sn=eee20d343a861d583c37ada884a4e1d3&amp;chksm=ead5b61cdda23f0a77035a92270f55e3b30daed04a7ed7fc6d61eee835c218503a7a9ec141ca#rd" target="_blank" rel="nofollow noopener noreferrer">使用JDBC操作SAP云平台上的HANA数据库</A><BR /> ● <A href="https://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247484513&amp;idx=1&amp;sn=a986b8a344ee943f6eead141d630c16c&amp;chksm=ead5b6f6dda23fe093350284a8d1f2cc15ba52553de127c5b1d5f01e3a325f45da2030656427#rd" target="_blank" rel="nofollow noopener noreferrer">使用Java程序消费SAP Leonardo的机器学习API</A><BR /> ● <A href="https://mp.weixin.qq.com/s?__biz=MzI3MDE4MjM5Mg==&amp;mid=2247483686&amp;idx=1&amp;sn=bbbf5ecf9cc3fa2a50545fafdb9c7417&amp;chksm=ead5b3b1dda23aa782e8bf7006d73d19e61f5bf06fed80498eb189e5791b4973319cf48103f5#rd" target="_blank" rel="nofollow noopener noreferrer">Jerry的ABAP, Java和JavaScript乱炖</A> 2018-06-06T06:11:14+02:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/calling-bapis-in-the-sap-s-4hana-public-cloud/ba-p/13411902 Calling BAPIs in the SAP S/4HANA Public Cloud 2019-06-14T13:58:57+02:00 former_member131481 https://community.sap.com/t5/user/viewprofilepage/user-id/131481 <H1 id="toc-hId-800618314">Introduction</H1><BR /> <H2 id="toc-hId-733187528">About this series</H2><BR /> In this blog series I will describe the use of RFC and BAPI technologies in the context of integration of the SAP S/4 HANA Public Cloud with On-Premise Systems. This kind of landscape is also called a Hybrid Landscape and we may as well talk about Hybrid Integration Scenarios.<BR /> <BR /> You will learn which technical components you need and how to configure them. The blog series is split into multiple parts. The first blog post is about the underlying concepts and the positioning and you are reading it right now. The details of the test case are described in individual blog posts.<BR /> <H2 id="toc-hId-536674023">Some background</H2><BR /> The specific case I am covering is the usage of "traditional" SAP integration technologies (RFC and BAPIs) which were partly whitelisted for usage with SAP S/4HANA Public Cloud. These technologies have been around for more than 20 years and were the work-horse concepts in the SAP ERP On-Premise world. But for the SAP Cloud they will only be required during a transition phase and will be replaced by SOAP and ODATA APIs as explained a bit further down.<BR /> <BR /> To give you some insight how to use them during this transition phase, I examined various test cases to illustrate what can be done. Please consider them as starting point for your own examinations. Of course I would be happy to learn about what you have tried and achieved. Just leave a note in the comment section below.<BR /> <BR /> BAPIs and RFC are sort of "ancient" SAP concepts for integration resp. communicating business information between systems. BAPI is an abbreviation for "Business Application Programming Interface". The offer a stable interface with standard methods to access SAP Business Objects (e.g. Sales Orders) which can be called externally. If you want to learn more I suggest you take a look at <A href="https://help.sap.com/doc/saphelp_autoid2007/2007/en-US/a5/3ec8464ac011d1894e0000e829fbbd/frameset.htm" target="_blank" rel="noopener noreferrer">this article in the SAP Documentation</A>.<BR /> <BR /> RFC is a technical protocol (Remote Function Call) which can be used to call RFC-enabled ABAP function modules from the outside. It was "the" protocol and came in various flavours, most importantly as so-called tRFC-Call (transactional RFC) which were of paramount importance for data exchange via ALE (Application Link Enabling), usually in the IDoc-Format. BAPIs are technically function modules of this type. We used to develop them ourselves based on the <A href="https://help.sap.com/doc/saphelp_snc70/7.0/en-US/7c/3ce38765ba11d395fe00a0c94260a5/frameset.htm" target="_blank" rel="noopener noreferrer">BAPI Programming Guide</A>&nbsp;and they could also be called asynchronously.<BR /> <BR /> Much more important than programming a BAPI yourself were those standard BAPIs which were delivered as part of the SAP standard. If you search for function modules starting with "BAPI_" in an SAP ERP System, you will find several thousands of them. This shows the importance of this concept in former times.<BR /> <H2 id="toc-hId-340160518">BAPIs in SAP S/4HANA Cloud – When And How To Use Them</H2><BR /> The standard way of integrating your SAP S/4HANA Cloud solution is with the help of <A href="https://rapid.sap.com/bp/#/browse/categories/sap_s%254hana/areas/cloud/packageversions/BP_CLD_ENTPR/S4CLD/1902/US/15?groupId=L1" target="_blank" rel="noopener noreferrer">SAP Best Practices</A> and <A href="https://api.sap.com/package/SAPS4HANACloud?section=Artifacts" target="_blank" rel="noopener noreferrer">whitelisted APIs</A>. For more information about these topics take a look at our&nbsp; “Integration with SAP S/4HANA Cloud” <A href="https://open.sap.com/courses/s4h10" target="_blank" rel="noopener noreferrer">openSAP course</A> and at our “SAP S/4HANA Cloud Integration Checklist” <A href="https://blogs.sap.com/2017/06/09/sap-s4hana-cloud-integration-checklist/" target="_blank" rel="noopener noreferrer">blog</A> post.<BR /> <BR /> The limited positioning of BAPIs in the context of SAP S/4HANA Cloud had long been explained in <A href="https://launchpad.support.sap.com/#/notes/2447593/E" target="_blank" rel="noopener noreferrer">SAP Note 2447593</A> and remains unchanged.<BR /> Here a quick recap:<BR /> <UL><BR /> <LI>SAP <STRONG>only</STRONG> supports BAPIs for the purpose of integrating SAP S/4HANA Cloud with SAP on-premise solutions (see also <A href="https://launchpad.support.sap.com/#/notes/2447593/E" target="_blank" rel="noopener noreferrer">SAP Note 2447593</A>)</LI><BR /> <LI>BAPIs listed in that note shall only be used until a successor API (OData or SOAP) has been made available</LI><BR /> <LI>If you need to use a BAPI interface for integrating with a 3<SUP>rd</SUP> party solution please follow the exception process as described in <A href="https://launchpad.support.sap.com/#/notes/2653671/E" target="_blank" rel="noopener noreferrer">SAP Note 2653671</A></LI><BR /> </UL><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/06/Image-Positioning-1.jpg" /><BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId-143647013">My Test Cases</H2><BR /> In the other parts of this Blog I will examine the following test cases:<BR /> <OL><BR /> <LI><A href="https://blogs.sap.com/2019/06/18/calling-a-bapi-in-the-sap-s4-hana-cloud-from-an-on-prem-sap-erp-system/" target="_blank" rel="noopener noreferrer"><STRONG>Calling a BAPI in the SAP S/4HANA Cloud from an on-prem SAP ERP System</STRONG></A><BR /> This was my starting point of this learning journey. I found out which components I needed and how to configure them. It was mainly about the SAP Cloud Connector (SCC) and how to set it up. I had never done that before and it was very educational. Once I got it to work the rest was straight forward. I will include a detailed description of the set-up process of the SCC which worked for me.</LI><BR /> <LI><A href="https://blogs.sap.com/2019/06/25/calling-a-bapi-in-the-sap-s4-hana-public-cloud-from-sap-process-orchestration/" target="_blank" rel="noopener noreferrer"><STRONG>Calling a BAPI in the </STRONG><STRONG>SAP S/4HANA Cloud from SAP Process Orchestration</STRONG></A><BR /> Building on top of test case 1, my colleague <SPAN class="mention-scrubbed">hoang.vu3#overview</SPAN> set up a scenario to call the BAPI from SAP Process Orchestration. This is a scenario that makes a lot of sense in a Hybrid Landscape because PO is a widespread tool in SAP-heavy On-Premise Landcapes.</LI><BR /> <LI><STRONG><A href="https://blogs.sap.com/2019/07/03/calling-a-bapi-in-the-sap-s4hana-cloud-from-a-non-sap-system/" target="_blank" rel="noopener noreferrer">Calling a BAPI in the SAP S/4HANA Cloud from a non-SAP system</A><BR /> </STRONG>I simulated this with a JAVA Program I ran in Eclipse. There are various RFC libraries available<STRONG>,</STRONG> the most prominent being the JCO Libraries also called SAP Java Connector.<STRONG><BR /> </STRONG></LI><BR /> <LI><A href="https://blogs.sap.com/2019/07/11/calling-a-bapi-in-an-sap-on-premise-system-from-the-cloud/" target="_blank" rel="noopener noreferrer"><STRONG>Calling a BAPI in an SAP On-premise system from the Cloud</STRONG></A><BR /> In this case I used SAP Cloud Platform Integration to make the call. It is sort of the reverse of test case 2 and has also some significance in real application scenarios.</LI><BR /> <LI><A href="https://blogs.sap.com/2019/07/11/calling-a-bapi-in-the-sap-s4hana-cloud-from-the-cloud/" target="_blank" rel="noopener noreferrer"><STRONG>Calling a BAPI in the SAP S/4HANA Cloud from the Cloud</STRONG></A><BR /> Direct RFC calls between SAP Cloud Components are not supported. What I wanted to find out was if it works if I take a detour via OnPrem.</LI><BR /> </OL><BR /> <H2 id="toc-hId--52866492">Important Reminder</H2><BR /> Please keep in mind what is pointed out in the section <STRONG>"BAPIs in SAP S/4HANA Cloud – When And How To Use Them"</STRONG>! What I describe in this series should be considered as experimental work and not as a recommendation for productive scenarios. If you want to use BAPIs for productive Cloud scenarios you must follow the process described in the notes mentioned above (<A href="https://launchpad.support.sap.com/#/notes/2653671/E" target="_blank" rel="noopener noreferrer">SAP Note 2653671</A> and <A href="https://launchpad.support.sap.com/#/notes/2447593/E" target="_blank" rel="noopener noreferrer">SAP Note 2447593</A>).<BR /> <H2 id="toc-hId--249379997"></H2><BR /> <H2 id="toc-hId--445893502">Preparation</H2><BR /> <H3 id="toc-hId--513324288">What I used</H3><BR /> <UL><BR /> <LI>An SAP Cloud Platform Account. It is needed to connect the SAP S/4 HANA Cloud Tenant and the SAP Cloud Connector.</LI><BR /> <LI>An SAP S/4HANA Public Cloud Tenant + user with administrative privileges</LI><BR /> <LI>An SAP Cloud Connector + user with administrative privileges</LI><BR /> <LI>An SAP ERP Backend System + user with RFC privileges</LI><BR /> <LI>SAP Process Orchestration + development user</LI><BR /> <LI>SAP Cloud Platform Integration Service + development user</LI><BR /> <LI>Eclipse (or comparable) + SAP Java Connector Libraries</LI><BR /> <LI>PostMan or SOAPUI</LI><BR /> </UL><BR /> The ERP Backend is especially useful to access the documentation of individual BAPIs. Call transaction BAPI to see the it. Use transaction SE37 to access the ABAP Implementation of the BAPI.<BR /> <BR /> <STRONG>Please be aware:</STRONG> Without access to an ERP backend you will have a hard time to obtain the BAPI documentation. It is not available online anymore or at least I couldn't find any. You can get a&nbsp; WSDL for a BAPI from an OnPrem ERP Backend or S/4HANA Backend via SAP Process Orchestration, too.<BR /> <H3 id="toc-hId--709837793">Helpful Knowledge</H3><BR /> <UL><BR /> <LI>How to do the Communication Setup in SAP S/4HANA Cloud: Communication Systems, Users and Scenarios</LI><BR /> <LI>Finding your way in the ABAP Workbench</LI><BR /> <LI>Basic RFC knowledge</LI><BR /> <LI>Basic BAPI knowledge</LI><BR /> <LI>Some JAVA</LI><BR /> <LI>How to develop simple IFlows in SAP Cloud Platform Integration.</LI><BR /> </UL><BR /> <H3 id="toc-hId--981582667">Quick Guide to set up the Cloud Connector</H3><BR /> In case you don't have an SAP Cloud Connector already available you need to set it up from scratch. There are a numerous blogs available how to do this. <A href="https://blogs.sap.com/2019/02/25/how-to-configure-sap-communication-scenario-step-by-step-guide/" target="_blank" rel="noopener noreferrer">This Blog by Ali Chalhoub</A> explains it very nicely and in much detail. Actually you should be fine to go with the documentation in the<A href="https://help.sap.com/viewer/f544846954f24b9183eddadcc41bdc3b/1905.500/en-US/82c9f05663594e5db8f923f6f88ae9bd.html" target="_blank" rel="noopener noreferrer"> SAP Help Library</A>. This part refers to online information resources which describe all the necessary steps in sufficient detail. The description is based on the 1905 documentation material. Steps 1-4 can be skipped if an already operational SCC-Setup can be used. Here is a quick overview if the steps:<BR /> <H3 id="toc-hId--1178096172">Step List</H3><BR /> <OL><BR /> <LI>Get the picture<BR /> Carefully read the chapter “Integrating OnPrem Systems” <A href="https://help.sap.com/viewer/f544846954f24b9183eddadcc41bdc3b/1905.500/en-US/82c9f05663594e5db8f923f6f88ae9bd.html" target="_blank" rel="noopener noreferrer">(1905 Version)</A> in section “General Functions for the Key User” of the SAP Online Help.</LI><BR /> <LI>Prepare and Configure the Cloud System<BR /> Configure Communication Scenario SAP_COM_0200 as described in “Integrating OnPrem Systems (Steps 1-7)”.</LI><BR /> <LI>Install the Cloud Connector<BR /> Download and Install the Cloud Connector “Integrating OnPrem Systems (Step 8)”<BR /> <A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/57ae3d62f63440f7952e57bfcef948d3.html" target="_blank" rel="noopener noreferrer">(SAP Cloud Platform Connectivity: Installation)</A></LI><BR /> <LI>Configure the Cloud Connector<BR /> Do the initial configuration of the Cloud Connector “Integrating OnPrem Systems (Step 9)”<BR /> <A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/db9170a7d97610148537d5a84bf79ba2.html" target="_blank" rel="noopener noreferrer">(SAP Cloud Platform Connectivity: Initial Configuration)</A></LI><BR /> <LI>Set up the Service Channel<BR /> Configure the Service Channel to your SAP S/4 HANA Cloud Tenant<BR /> <A href="https://help.sap.com/viewer/DRAFT/f544846954f24b9183eddadcc41bdc3b/1902.500/en-US/0d36508f6f1f4eae846acd4b5887560f.html" target="_blank" rel="noopener noreferrer">(Setting Up the Connection from On-Premise Systems to SAP S/4HANA Cloud)</A><BR /> <A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/18602c25ae33423f847e9f2c539d7fa0.html" target="_blank" rel="noopener noreferrer">(Configure a Service Channel for RFC)</A></LI><BR /> <LI>Test the Connection</LI><BR /> <LI>Use the Setup</LI><BR /> </OL><BR /> <H3 id="toc-hId--1374609677">Preparing the SAP S/4 HANA Cloud System</H3><BR /> Once the SCC Setup is working properly a Communication Scenario with BAPIs can be used:<BR /> <OL><BR /> <LI>Take a look at OSS-Note <A href="https://launchpad.support.sap.com/#/notes/2447593/E" target="_blank" rel="noopener noreferrer">2447593 - Available BAPIs in S/4HANA Cloud for integration to SAP on Premise solutions</A> to identify the Communication Scenario you want to use.</LI><BR /> <LI>Activate the Communication Scenario in the S/4HANA Cloud System. My example: Read an Equipment.</LI><BR /> <LI>For example: <STRONG>BAPI_EQUI_GETDETAI</STRONG>L. The note shows we need to activate <STRONG>SAP_COM_0319</STRONG>.</LI><BR /> <LI>Go to Communication Arrangements and create a new arrangement from Scenario SAP_COM_0319.</LI><BR /> <LI>Pick the same communication system as for SAP_COM_0200. The inbound user is filled in automatically since it is attached to the communication scenario.</LI><BR /> <LI>In the arrangement you can see the available BAPIs. Save the arrangement:</LI><BR /> </OL><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/06/F3_COM_0319.png" /><BR /> <BR /> &nbsp;<BR /> <BR /> Your components should now be ready for operation!<BR /> <BR /> <A href="https://blogs.sap.com/2019/06/18/calling-a-bapi-in-the-sap-s4-hana-cloud-from-an-on-prem-sap-erp-system/" target="_blank" rel="noopener noreferrer"> In the next blog post I will go into detail for test case 1</A>. 2019-06-14T13:58:57+02:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/calling-a-bapi-in-the-sap-s-4hana-cloud-from-a-non-sap-system/ba-p/13391096 Calling a BAPI in the SAP S/4HANA Cloud from a non-SAP system 2019-07-03T18:42:57+02:00 former_member131481 https://community.sap.com/t5/user/viewprofilepage/user-id/131481 <H2 id="toc-hId-908451684">Introduction</H2><BR /> In the <A href="https://blogs.sap.com/2019/06/25/calling-a-bapi-in-the-sap-s4-hana-public-cloud-from-sap-process-orchestration/" target="_blank" rel="noopener noreferrer">previous blog post of this series</A> we saw how to call a whitelisted BAPI in the SAP S/4HANA Cloud using SAP Process Orchestration. Now we are going to take a look how we can do the same from a non-SAP application.<BR /> <H2 id="toc-hId-711938179">Calling a BAPI in the Cloud from non-SAP systems ( e.g. a JAVA program)</H2><BR /> Non-SAP systems can make RFC-Calls to the S/4HANA Cloud as long as they adhere to the RFC standards. That is usually done by implementing the libraries which were published by SAP. There are numerous solutions available which implement the RFC protocol this way and are certified. These 3rd party products usually come along with a guide which explains how to integrate with SAP systems. For SAP On-Premise solutions it has been like this for many years. For the SAP S/4HANA Cloud it works as well (as we will see) but there are some official restrictions:<BR /> <BR /> Please keep <A href="https://launchpad.support.sap.com/#/notes/2447593/E" target="_blank" rel="noopener noreferrer">SAP Note 2447593</A> in mind which is saying that RFC should only be used to integrate S/4 HANA Cloud with SAP OnPremise-Solutions (and be it, that it is SAP PO). So whatever you do with non-SAP systems, RFC/BAPI and the SAP S/4HANA Cloud is at your own risk.<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/06/TC3.jpg" /><BR /> <H2 id="toc-hId-515424674">Preparation</H2><BR /> <H3 id="toc-hId-447993888">What I used</H3><BR /> <UL><BR /> <LI>A functional SAP Cloud Connector Instance + user with administrative privileges</LI><BR /> <LI>An SAP S/4 HANA Public Cloud Tenant + user with administrative privileges</LI><BR /> <LI>Eclipse</LI><BR /> <LI>SAP JCO libraries</LI><BR /> </UL><BR /> <H3 id="toc-hId-251480383">What I did</H3><BR /> <UL><BR /> <LI>Download the JCO libraries</LI><BR /> <LI>Import the JCO libraries into Eclipse</LI><BR /> <LI>Set up the JCO Destination File</LI><BR /> <LI>Test the connection and the BAPI call with the sample programs</LI><BR /> </UL><BR /> <H3 id="toc-hId-54966878">Setting up Eclipse</H3><BR /> One way of simulating a non-SAP System is making use of a SAP Connector, the JCO libraries. You can find them here: <A href="https://support.sap.com/en/product/connectors/jco.html#section" target="_blank" rel="noopener noreferrer">SAP Java Connector</A>. In my example I set up an Eclipse Project and implemented a program that was based on the samples provided with the JCO library. I had to play around a little bit but in the end it worked.<BR /> <BR /> Being not much of a Java guy, I was inspired by 2 Blogs from <SPAN class="mention-scrubbed">varun.boyina#overview</SPAN> which helped me to set up the example.<BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <UL><BR /> <LI class="dm-contentHero__title"><A href="https://blogs.sap.com/2016/05/19/sap-ui-5-calling-rfc-through-sap-jco-2/" target="_blank" rel="noopener noreferrer">SAP UI 5 – CALLING RFC THROUGH SAP JCO</A></LI><BR /> </UL><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <UL><BR /> <LI class="dm-contentHero__title"><A href="https://blogs.sap.com/2016/05/16/sap-ui5-calling-servletwhich-returns-single-value-using-jquery-ajax/" target="_blank" rel="noopener noreferrer">SAP UI5 – Calling Servlet(which Returns Single Value) using JQUERY AJAX</A></LI><BR /> </UL><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> Initially I wanted to go via the good old RFC libraries which were used to be delivered with the SAP GUI and included such useful programs like startrfc.exe but that isn’t the case anymore. You can still download a NW RFC library if you want to (<A href="https://support.sap.com/en/product/connectors/nwrfcsdk.html" target="_blank" rel="noopener noreferrer">see here</A>) but startrfc doesn’t work the way I thought it did anymore or maybe I’m mixing things up and don't remember it properly. The last time I actually used startrfc was about 15 years ago. Programs change, memories fade…<BR /> <BR /> Eclipse and the JCO worked fine for me and anybody who is more familiar with Eclipse and Java should get along easily.The project structure in Eclipse looks like this:<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/06/Eclipse.jpg" /><BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--141546627">JCO Destination File</H3><BR /> You can either put the destination details into the program or put an RFC destination file into the project. This file contains the information to establish a connection:<BR /> <PRE class="language-java"><CODE>#for tests only !<BR /> #Tue May 15 16:51:44 CET 2019<BR /> jco.client.lang=EN<BR /> jco.client.client=100<BR /> jco.client.passwd= &lt;Put the password of the S4HC API User of the CommScenario here&gt;<BR /> jco.client.user=&lt;Put the name of the S4HC API User of the CommScenario here&gt;<BR /> jco.client.sysnr=00<BR /> jco.client.ashost=&lt;Adress of the SCC, e.g. xxx.mo.sap.corp&gt;<BR /> </CODE></PRE><BR /> If you get a RFC_NO_AUTHORIZATION in BAPI_METADATA_GET error you could try this:<BR /> <BR /> <STRONG><EM>jco.destination.repository_roundtrip_optimization</EM>=0</STRONG><BR /> <BR /> (Thank you Jacky Liu, Ban Luo and Echo Chen for finding the solution and testing it)<BR /> <BR /> In the example the file is called "SCC_PRACTICE.jcoDestination". You can see it in the project structure above. You need to put your own destination details for passwd, user and ashost.<BR /> <H3 id="toc-hId--338060132">Sample Program</H3><BR /> With the program below I was able to read equipment data from the S/4 HANA Cloud. It is a very basic program and not dynamic at all. But it shows that actually not much is required to do the calls. If you want to get into the details I recommend that you read the documentation: <A href="https://support.sap.com/content/dam/support/en_us/library/ssp/products/connectors/jco/jco_30_documentation_en.pdf" target="_blank" rel="noopener noreferrer">SAP Java Connector (Standalone Version).</A><BR /> <PRE class="language-java"><CODE>package jne;<BR /> <BR /> <BR /> <BR /> import com.sap.conn.jco.AbapException;<BR /> // import com.sap.conn.jco.JCoContext;<BR /> import com.sap.conn.jco.JCoDestination;<BR /> import com.sap.conn.jco.JCoDestinationManager;<BR /> import com.sap.conn.jco.JCoException;<BR /> // import com.sap.conn.jco.JCoField;<BR /> import com.sap.conn.jco.JCoFunction;<BR /> // import com.sap.conn.jco.JCoFunctionTemplate;<BR /> import com.sap.conn.jco.JCoStructure;<BR /> // import com.sap.conn.jco.JCoTable;<BR /> // import com.sap.conn.jco.ext.DestinationDataProvider;<BR /> <BR /> /**<BR /> * basic examples for Java to ABAP communication <BR /> */<BR /> public class RFCBAPI<BR /> {<BR /> // static String SCC = "SCC_JNE";<BR /> static String SCC = "SCC_PRACTICE";<BR /> <BR /> <BR /> /**<BR /> * This example demonstrates the destination concept introduced with JCO 3.<BR /> * The application does not deal with single connections anymore. Instead<BR /> * it works with logical destinations like ABAP_AS and ABAP_MS which separates<BR /> * the application logic from technical configuration. <BR /> * @throws JCoException<BR /> */<BR /> public static void step1Connect() throws JCoException<BR /> {<BR /> JCoDestination destination = JCoDestinationManager.getDestination(SCC);<BR /> System.out.println("Attributes:");<BR /> System.out.println(destination.getAttributes());<BR /> System.out.println();<BR /> <BR /> <BR /> }<BR /> <BR /> <BR /> public static void step5CallBAPI() throws JCoException<BR /> {<BR /> System.out.println("Initiating");<BR /> JCoDestination destination = JCoDestinationManager.getDestination(SCC);<BR /> System.out.println("Calling:");<BR /> JCoFunction function = destination.getRepository().getFunction("BAPI_EQUI_GETDETAIL");<BR /> if(function == null)<BR /> throw new RuntimeException("BAPI_EQUI_GETDETAIL not found in SAP.");<BR /> try<BR /> {<BR /> function.getImportParameterList().setValue("EQUIPMENT", "000000000010000000");<BR /> function.execute(destination);<BR /> }<BR /> catch(AbapException e)<BR /> {<BR /> System.out.println("ABAP Exception"); <BR /> System.out.println(e.toString());<BR /> }<BR /> try<BR /> {<BR /> System.out.println("BAPI_EQUI_GETDETAIL finished:");<BR /> // System.out.println(function.toXML());<BR /> printStruct(function,"DATA_GENERAL_EXP");<BR /> // printStruct(function,"DATA_SPECIFIC_EXP");<BR /> // printStruct(function,"DATA_FLEET_EXP");<BR /> // printStruct(function,"RETURN");<BR /> }<BR /> catch(Exception e)<BR /> {<BR /> e.printStackTrace();<BR /> }<BR /> }<BR /> <BR /> <BR /> public static void step6PrintBAPI() throws JCoException<BR /> {<BR /> System.out.println("Initiating:");<BR /> JCoDestination destination = JCoDestinationManager.getDestination(SCC);<BR /> System.out.println("Calling:");<BR /> JCoFunction function = destination.getRepository().getFunction("BAPI_EQUI_GETDETAIL");<BR /> if(function == null)<BR /> throw new RuntimeException("BAPI_EQUI_GETDETAIL not found in SAP.");<BR /> try<BR /> {<BR /> function.getImportParameterList().setValue("EQUIPMENT", "000000000010000000");<BR /> // function.getImportParameterList().setValue("REQUEST_INSTALLATION_DATA", "X");<BR /> function.execute(destination);<BR /> }<BR /> catch(AbapException e)<BR /> {<BR /> System.out.println("ABAP Exception"); <BR /> System.out.println(e.toString());<BR /> }<BR /> try<BR /> {<BR /> System.out.println("BAPI_EQUI_GETDETAIL finished:");<BR /> System.out.println(function.toXML());<BR /> // System.out.println(function.getFunctionTemplate());<BR /> // printStruct(function,"DATA_GENERAL_EXP");<BR /> // printStruct(function,"DATA_SPECIFIC_EXP");<BR /> // printStruct(function,"DATA_FLEET_EXP");<BR /> // printStruct(function,"RETURN");<BR /> }<BR /> catch(Exception e)<BR /> {<BR /> e.printStackTrace();<BR /> }<BR /> }<BR /> <BR /> public static void printStruct(JCoFunction BAPI, String StrucName) {<BR /> <BR /> System.out.println("\n" + "Structure: " + StrucName);<BR /> JCoStructure BAPIStruc = BAPI.getExportParameterList().getStructure(StrucName);<BR /> for (int i = 0; i &lt; BAPIStruc.getFieldCount(); i++)<BR /> {<BR /> System.out.println(i + ": " + BAPIStruc.getString(i));;<BR /> } <BR /> }<BR /> <BR /> <BR /> public static void main(String[] args) throws JCoException<BR /> {<BR /> // Set Destination <BR /> <BR /> // step0DestinationFile();<BR /> step1Connect();<BR /> // step2ConnectUsingPool();<BR /> // step3SimpleCall();<BR /> // step4WorkWithTable();<BR /> // step4SimpleStatefulCalls();<BR /> // step5CallBAPI();<BR /> step6PrintBAPI();<BR /> }<BR /> }<BR /> <BR /> </CODE></PRE><BR /> <H2 id="toc-hId--663656356">Conclusion</H2><BR /> <H3 id="toc-hId--731087142">What I learned from this test case</H3><BR /> With this test case I brushed up my Java a little bit. For somebody who has used the JCO libraries already in the OnPrem world there is nothing new. The implementation is the same, just the RFC Destination is pointing to the SAP Cloud Connector.<BR /> <H3 id="toc-hId--1002832016">Your Feedback</H3><BR /> Please let me know if the description was helpful and you were able to set up the same test case. Any feedback how to improve this blog post is welcomed! Please put it in the comment section.<BR /> <H3 id="toc-hId--1199345521">What’s next</H3><BR /> Next time I will show you how to call a BAPI on-premise from SAP Cloud Platform Integration. It's also the preparation for the final test case in which I do a call from the Cloud and back. Check back soon!<BR /> <BR /> &nbsp; 2019-07-03T18:42:57+02:00 https://community.sap.com/t5/technology-blogs-by-members/sap-hana-xsa-code-jam-en-ciudad-de-mexico-2019/ba-p/13412139 SAP Hana XSA Code Jam en Ciudad de Mexico ?? 2019 2019-08-03T03:31:09+02:00 MariettaLopez https://community.sap.com/t5/user/viewprofilepage/user-id/797 <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/SAPCodeJamMexico.png" /><BR /> <H3 id="toc-hId-1058805955">Este 21 de Agosto en la Ciudad de México de 9 AM a 3 PM estaremos llevando a cabo un <SPAN class="_5afx"><SPAN class="_58cm"><A href="https://www.sap.com/index.html" target="_blank" rel="noopener noreferrer"><STRONG>SAP</STRONG></A> </SPAN></SPAN><STRONG><SPAN class="_5afx"><SPAN class="_58cl _5afz" aria-label="hashtag">#</SPAN><SPAN class="_58cm">HANA</SPAN></SPAN>&nbsp;<SPAN class="_5afx"><SPAN class="_58cl _5afz" aria-label="hashtag">#</SPAN><SPAN class="_58cm">XSA Code Jam</SPAN></SPAN></STRONG> junto con el <STRONG><A href="https://www.sap.com/index.html" target="_blank" rel="noopener noreferrer">SAP</A> Inside Track Mexico 2019</STRONG> un evento donde podrás desarrollar una solución utilizando diversas tecnologías, plataformas y herramientas de <A href="https://www.sap.com/index.html" target="_blank" rel="noopener noreferrer">SAP.</A> Se le presentará un escenario de inicio a fin, en el que podrá ver cómo las diferentes tecnologías se integran y trabajan juntas mientras construye su solución.</H3><BR /> &nbsp;<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/Screenshot-2019-05-14-21.35.39.png" height="177" width="326" /><BR /> <H3 id="toc-hId-862292450">Es un evento GRATUITO, pero como es un evento práctico tiene ciertos requerimientos para poder participar</H3><BR /> <H2 id="toc-hId-536696226">Debes traer tu propia computadora portátil) <SPAN class="text_exposed_show">y de preferencia q tengas #HANA #<SPAN class="_5afx"><SPAN class="_58cm">Express instalado</SPAN></SPAN></SPAN></H2><BR /> &nbsp;<BR /> <DIV><BR /> <H3 id="toc-hId-469265440"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/08/Screenshot-2019-08-02-20.18.05.png" height="268" width="206" /></H3><BR /> <H3 id="toc-hId-272751935">La ponencia estará dictada por la catedrática&nbsp;<SPAN class="mention-scrubbed">lsubatin</SPAN>&nbsp;de <A href="https://www.sap.com/index.html" target="_blank" rel="noopener noreferrer">@SAP</A>, experta en la materia, que estará en el sitio para responder a sus preguntas y compartir información y consejos relevantes.</H3><BR /> <H3 id="toc-hId-76238430"><SPAN lang="ES">If you are a</SPAN><SPAN lang="ES">&nbsp;</SPAN><SPAN lang="ES"><A href="https://www.sap.com/" target="_blank" rel="noopener noreferrer">SAP</A></SPAN><SPAN lang="ES">&nbsp;programmer, who seeks to know or update,</SPAN></H3><BR /> <H2 id="toc-hId--249357794"><STRONG>Made your pre-register <A href="https://www.eventbrite.com/e/sap-codejam-ciudad-de-mexico-registration-68050072599" target="_blank" rel="nofollow noopener noreferrer">ASAP</A></STRONG></H2><BR /> </DIV><BR /> <STRONG><EM>Organizers:</EM></STRONG><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/Screenshot-2019-05-14-19.40.02-1.png" /><BR /> <BR /> <STRONG><EM><SPAN class="mention-scrubbed">maria.antonieta.lopez</SPAN></EM></STRONG><BR /> <BR /> <STRONG><EM><SPAN class="mention-scrubbed">jhonjairoteran#overview</SPAN></EM></STRONG><BR /> <BR /> <STRONG><EM><SPAN class="mention-scrubbed">9958e4b6df99431a84a41b015b639ac8#overview</SPAN></EM></STRONG><BR /> <DIV><BR /> <H2 id="toc-hId--445871299">Sponsors</H2><BR /> <A href="https://www.sap.com/" target="_blank" rel="noopener noreferrer"><STRONG>SAP</STRONG></A>&nbsp;<STRONG>Mexico will kindly provide us the place for the event </STRONG><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/SAP-logo.gif" height="171" width="313" /><BR /> <P id="tw-target-text" class="tw-data-text tw-ta tw-text-small" dir="ltr" data-placeholder="Translation"><STRONG><SPAN lang="en">The <A href="https://www.sap.com/community.html" target="_blank" rel="noopener noreferrer">SAP Community</A> will support us with a lunch for the attendees.</SPAN></STRONG></P><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/Screenshot-2019-05-12-15.23.19.png" /><BR /> <BR /> <STRONG>SAP PRESS</STRONG><BR /> <BR /> <STRONG>Attendees who stay at the end of the event will receive a 15% discount on their purchases at the &nbsp;<A class="jive-link-external-small" href="https://www.sap-press.com/" target="_blank" rel="nofollow noopener noreferrer">SAP Press</A> store and will be able to win one of the 2 e-books we will raffle!</STRONG><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2016/04/press_1029908.png" height="230" width="419" /><BR /> <BR /> &nbsp;<BR /> <BR /> <STRONG><SPAN lang="en">We also have the sponsorship of the <A href="https://espresso-tutorials.com/" target="_blank" rel="nofollow noopener noreferrer">Espresso Tutorials</A>, attendees who stay at the end of the event will receive access to their content online for 1 month.</SPAN></STRONG><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/espresso-tutorials-logo-1.png" height="89" width="312" /><BR /> <BR /> <STRONG>Apoyo:</STRONG><BR /> <BR /> <EM><A href="https://www.sap.com/community/resources/influencer-programs/mentors.html" target="_blank" rel="noopener noreferrer"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2016/04/thumbnail_942597.png" height="56" width="443" /></A></EM><BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--642384804"><STRONG>Important Facts</STRONG></H2><BR /> <EM><STRONG>Date and Hours:</STRONG> August </EM>21, 2019 from 09:00 to 15:00 hrs.<BR /> <BR /> <EM><STRONG>Address:</STRONG> Prolongación&nbsp;Paseo de la Reforma 600, Santa Fe, Zedec Sta Fé, 01210 Ciudad de México, CDMX</EM><BR /> <BR /> <STRONG>Hashtag</STRONG>:<BR /> <BR /> <EM>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#CodeJamMEX</EM><BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--838898309">CONTACT</H2><BR /> ?<span class="lia-unicode-emoji" title=":envelope:">✉️</span>&nbsp;<STRONG><A href="https://www.sap.com/index.html" target="_blank" rel="noopener noreferrer">SAP</A><A href="https://blogs.sap.com/2019/05/15/sap-inside-track-de-la-ciudad-de-mexico-mex-%f0%9f%87%b2%f0%9f%87%bd-2019/comment-page-1/sapinsidetrackmexico@gmail.com" target="_blank" rel="noopener noreferrer">InsideTrackMexico@gmail.com</A></STRONG><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/download-1.png" height="31" width="32" />&nbsp;<A href="https://twitter.com/InsideTrackMEX" target="_blank" rel="nofollow noopener noreferrer">@InsideTrackMEX</A><BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2019/05/face.png" height="29" width="29" /><STRONG>&nbsp;@<A href="https://www.sap.com/index.html" target="_blank" rel="noopener noreferrer">SAP</A><A href="https://www.facebook.com/SAP.Inside.Track.Mex/" target="_blank" rel="nofollow noopener noreferrer">.Inside.Track.Mex</A></STRONG><BR /> <DIV><BR /> <DIV><BR /> <DIV><BR /> <DIV></DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV><BR /> </DIV> 2019-08-03T03:31:09+02:00 https://community.sap.com/t5/technology-blogs-by-members/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector/ba-p/13431769 Produce/consume messages in KAFKA with SAP Netweaver using Java Connector - Part 1/3 2020-04-14T14:11:48+02:00 michael_pang4 https://community.sap.com/t5/user/viewprofilepage/user-id/245249 <H1 id="toc-hId-802463627">Introduction</H1><BR /> Is it possible to produce/send a message from SAP to KAFKA using ABAP? What about is it possible to consume/receive a message in SAP from KAFKA?<BR /> <BR /> In this blog I'll demonstrate how it is possible to do this using the SAP Java Connector and the Apache Java API.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId-605950122">Use case</H1><BR /> We live in a world where we need to reduce data friction between systems. Let's suppose you are asked to send the details (say a business partner) out to a Kafka topic as changes happen inside SAP. As a developer you've located the perfect user exit/BADI that gets triggered on/after save where you can put your ABAP code. Now you are stuck. How do you go from taking all the data in ABAP memory, and pass it to KAFKA?<BR /> <BR /> Kafka cannot receive HTTP calls out of the box. You need to use a Java API, or a third party API, or setup an intermediate server to translate HTTP calls to call Kafka.<BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId-409436617">What are my options?</H1><BR /> There are heaps of options to produce/consume messages in KAFKA. Some free, others are not, all with their pros and cons.&nbsp; <A href="https://kafka.apache.org/documentation/" target="_blank" rel="nofollow noopener noreferrer">Apache</A> has a Java client, and <A href="https://docs.confluent.io/current/clients/index.html" target="_blank" rel="nofollow noopener noreferrer">Confluent.io</A> has a tonnes of options - .NET, Go, Python etc. There are also heaps of <A href="https://cwiki.apache.org/confluence/display/KAFKA/Clients" target="_blank" rel="nofollow noopener noreferrer">third party</A> options to support other languages as well.<BR /> <BR /> ABAP to Kafka connector? Well, you are out of luck here (at least at the time of this article).<BR /> <BR /> The obvious choice for the unsupported languages is to host a <A href="https://www.confluent.io/blog/a-comprehensive-rest-proxy-for-kafka/" target="_blank" rel="nofollow noopener noreferrer">HTTP/REST API</A> for any systems to call. Confluent has a REST support as well.<BR /> <BR /> There are also options where you can stream straight from the database/HANA/hadoop as well. I'm not quite sure how that's going to work for SAP data, where the data is spread across multiple tables and don't always make sense to the outside world.<BR /> <BR /> You can spend days exploring the different options, so choose the one that suits.<BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId-212923112">What about standard SAP and third party enterprise products?</H1><BR /> SAP of course have their standard solutions, such as SAP Data Hub, SAP HANA Connector, and possibly others. I have not tried them. There are also other third party companies that provide enterprise solutions at a cost, such as Ad. Google it or search on SDN, all with their pros and cons.<BR /> <BR /> When I first started, I was hoping there could be a standard SAP KAFKA class that I can call to send a message, but there isn't one. I've read a blog that talked about using ABAP Channels but it didn't work for us.<BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId-16409607">Disclaimer</H1><BR /> <UL><BR /> <LI>I'm not here to say which solution is better as I don't know. My intention is not to compete with the various products/solutions out there either. As a techie, I just want to see what is possible. To me this option might be the cheapest one without the need of extra hardware or too much setup.</LI><BR /> <LI>This is not a tutorial on Java, or <A href="https://kafka.apache.org/documentation/" target="_blank" rel="nofollow noopener noreferrer">KAFKA</A>, AWS, or how to run your own Netweaver environment. It does require knowledge on all of these to follow what I'm doing, so let's hope you can follow along.</LI><BR /> <LI>This is also not a production scale demo. There are many tweaks you can do to make this scale.</LI><BR /> <LI>This demo will cost you money for cloud hosting if you were to follow.</LI><BR /> </UL><BR /> Hopefully some of you will find this interesting. It took me a couple of nights to understand how to setup a JCO server properly as the standard SAP documentation is not the best.<BR /> <H1 id="toc-hId--180103898">What am I going to do?</H1><BR /> <OL><BR /> <LI>Setup a demo Netweaver system using SAP CAL (Cloud Appliance Library) in AWS</LI><BR /> <LI>Setup some tools that I'm going to use in the EC2 instance</LI><BR /> <LI>Setup KAFKA</LI><BR /> <LI>Setup SAP Java Connector (JCo)</LI><BR /> <LI>Create/configure SAP Java Connector Server</LI><BR /> <LI>Produce a message to a KAFKA topic from ABAP</LI><BR /> <LI>Consume a message from a KAFKA topic and call ABAP</LI><BR /> </OL><BR /> &nbsp;<BR /> <H1 id="toc-hId--376617403">Versions</H1><BR /> <UL><BR /> <LI>KAFKA - 2.12</LI><BR /> <LI>SAP Java Connector (JCo) - 3.0</LI><BR /> <LI>SAP NetWeaver AS ABAP 7.51 SP02 on ASE</LI><BR /> </UL><BR /> &nbsp;<BR /> <H1 id="toc-hId--573130908">Source code</H1><BR /> I've put my code on github.... you might find it useful.<BR /> <BR /> <A href="https://github.com/joymike/sap_kafka_demo.git" target="_blank" rel="nofollow noopener noreferrer">https://github.com/joymike/sap_kafka_demo.git</A><BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId--769644413">Blog links</H1><BR /> <A href="https://blogs.sap.com/2020/04/14/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector-part-1-3/" target="_blank" rel="noopener noreferrer">Produce/consume messages in KAFKA with SAP Netweaver using Java Connector – Part 1/3</A><BR /> <BR /> <A href="https://blogs.sap.com/2020/04/14/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector-part-2-3/" target="_blank" rel="noopener noreferrer">Produce/consume messages in KAFKA with SAP Netweaver using Java Connector – Part 2/3</A><BR /> <BR /> <A href="https://blogs.sap.com/2020/04/14/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector-part-3-3/" target="_blank" rel="noopener noreferrer">Produce/consume messages in KAFKA with SAP Netweaver using Java Connector – Part 3/3</A><BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId--966157918">Architecture</H1><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/SAP-KAFKA-DrawIO.jpg" /><BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H1 id="toc-hId--392931340">Setup a demo NW system in SAP CAL</H1><BR /> <SPAN style="color: #ff0000"><EM><STRONG>If you do this, it will cost you money!!!&nbsp;</STRONG></EM></SPAN><BR /> <H2 id="toc-hId--882847852">SAP Cloud Appliance Library (CAL)</H2><BR /> Go to SAP Cloud Appliance Library - <A href="https://cal.sap.com/" target="test_blank" rel="noopener noreferrer">https://cal.sap.com/</A>, register and create a new "SAP Netweaver AS ABAP 7.51 SP02 on ASE" instance on AWS. You will be presented with many solution choices, so you can pretty much choose any NW instances available. Some options are slightly cheaper than others. You can choose other cloud providers like Google Cloud or Azure. Like I said I'm not here teach you how to use CAL here, so I'm sure you can google it and find out.<BR /> <BR /> When I first tried to do so, it didn't work, but a day later I got an email and I went in again and it worked again. I can choose from 113 solutions, it's really quite fascinating!<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/SAP-CAL.png" /><BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--1372764364">Cost</H3><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/SAP-CAL-cost.png" /></P><BR /> <BR /> <H3 id="toc-hId--1569277869">Tips</H3><BR /> Download the Key and save it somewhere (Don't lose it)<BR /> <BR /> Remember the password you entered to create the instance with CAL. There's no way of recovering (that I know of), and you'll need to that to use the SAP system.<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--1472388367">Amazon AWS EC2</H2><BR /> As you can see there are two instances created. These are not covered in Amazon AWS free tier so they will cost you some money.<BR /> <BR /> After a while, I have 2x AWS EC2 instances:<BR /> <UL><BR /> <LI>a SUSE Enterprise Linux server instance installed with the SAP Netweaver with HANA backend, installed and ready to go.</LI><BR /> <LI>a Windows instance with SAPGUI and all the development tools you'll need (you may or may not need this, you can delete it to save some money if you got all the tools installed on your laptop already)</LI><BR /> </UL><BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/AWS-EC2.png" /></P><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--1962304879">Tips</H3><BR /> <UL><BR /> <LI>I have SAPGUI installed on my laptop</LI><BR /> <LI>I've attached an elastic IP to my instances so that the Public DNS and IP does not change after EC2 restart.</LI><BR /> <LI>Turn of your EC2 instances if you are not using it. It cost less than USD$0.50 per hour but it does add up over time.</LI><BR /> <LI>Setup cost alarms in AWS to warn you if you go over your budget.</LI><BR /> <LI>I've setup a AWS CloudWatch event that calls a Lambda function to switch off my EC2 instances every hour to safe cost. Yes it's inconvenient but I make sure I don't get a nasty surprise.</LI><BR /> <LI>Again, this is not a tutorial about AWS, so go google it and I'm sure you can find out <span class="lia-unicode-emoji" title=":grinning_face_with_smiling_eyes:">😄</span></LI><BR /> </UL><BR /> &nbsp;<BR /> <H3 id="toc-hId-2136148912">SSH into the Linux instance</H3><BR /> You can use PUTTY (for Windows) or just terminal for Mac. I'm sure you can work out how to do this with a quick googling around.<BR /> <BR /> Now notice the user created is "root", and password is the same password you entered for CAL when you created the instance. You need to provide the key/cert to log in.<BR /> <BR /> For Putty you will need to convert the cert using PUTTYGEN first.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> See you in part 2!<BR /> <BR /> &nbsp;<BR /> <BR /> Leave me some comments so I know how I went. 2020-04-14T14:11:48+02:00 https://community.sap.com/t5/technology-blogs-by-members/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector/ba-p/13433006 Produce/consume messages in KAFKA with SAP Netweaver using Java Connector – Part 2/3 2020-04-14T14:12:29+02:00 michael_pang4 https://community.sap.com/t5/user/viewprofilepage/user-id/245249 This is the second part to demonstrating how to get SAP Netweaver to produce/consume messages in KAFKA from SAP.<BR /> <BR /> Link to part 1 <A href="https://blogs.sap.com/2020/04/14/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector-part-1-3/" target="_blank" rel="noopener noreferrer">Part 1</A><BR /> <BR /> &nbsp;<BR /> <BR /> If you are just keen to see the results, go to <A href="https://blogs.sap.com/2020/04/14/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector-part-3-3/" target="_blank" rel="noopener noreferrer">Part 3</A>.<BR /> <BR /> &nbsp;<BR /> <BR /> Below will cover the following:<BR /> <UL><BR /> <LI>Connect to your SAP server using SAPGUI<BR /> <UL><BR /> <LI>Install license</LI><BR /> <LI>Developer Key</LI><BR /> </UL><BR /> </LI><BR /> <LI>Setting up tools<BR /> <UL><BR /> <LI>Java Development Kit</LI><BR /> <LI>Nano</LI><BR /> </UL><BR /> </LI><BR /> <LI>Setting up KAFKA</LI><BR /> <LI>Setting up SAP Java Connector (JCo)</LI><BR /> </UL><BR /> &nbsp;<BR /> <BR /> Just to reiterate, I didn't use the windows EC2 instance that had all the developer tools. I only used the SUSE linux instance installed with the SAP Netweaver backend.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId-931599012">Source code</H2><BR /> I've put my code on <A href="https://github.com/joymike/sap_kafka_demo.git" target="_blank" rel="nofollow noopener noreferrer">github</A>.... you might find it useful.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId-735085507">Setup your SAP system</H2><BR /> You can either use your windows EC2 instance's SAPGUI and it is already setup with a system to connect to.<BR /> <BR /> If you have your own SAPGUI installed on your own machine. The application server should point to your elastic IP of your EC2 instance, or else it may change after every EC2 restart.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/SAPGUI-Param.png" /></P><BR /> &nbsp;<BR /> <H3 id="toc-hId-667654721">First log in</H3><BR /> Client 001<BR /> <BR /> User: DEVELOPER<BR /> <BR /> Password: What you entered when you created your CAL instance<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId-471141216">Install trial license</H3><BR /> See <A href="https://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=526880970" target="_blank" rel="noopener noreferrer">here</A> , or google how to get a minisap license.<BR /> <P style="overflow: hidden;margin-bottom: 0px">In a nutshell, get your hardware key from transaction transaction SLICENSE.</P><BR /> Go to <A href="https://go.support.sap.com/minisap/#/minisap" target="test_blank" rel="noopener noreferrer">https://go.support.sap.com/minisap/#/minisap</A> and generate a license for A4H, enter your hardware key.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/minisap-license.png" />Upload it to SLICENSE and you are done.</P><BR /> &nbsp;<BR /> <H3 id="toc-hId-274627711">Developer key</H3><BR /> The user DEVELOPER should already have a developer key assigned, so in case you are wondering, you don't need one. Just don't go and create your own user and expect to be able to get a developer key for it (I found out the hard way).<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--50968513"><SPAN style="text-decoration: underline">Setting up tools</SPAN></H2><BR /> First you need to make sure you can SSH into your EC2 instance.<BR /> <H3 id="toc-hId--118399299">JDK</H3><BR /> Both KAFKA and SAP Java Connector requires Java, so it makes sense to start installing that first.<BR /> <BR /> From memory a Java 1.6 comes with the EC2 instance but it is too old for KAFKA, so we need a newer one.<BR /> <H4 id="toc-hId--185830085">To install</H4><BR /> Run command:<BR /> <PRE class="language-javascript"><CODE>sudo zypper --non-interactive install java-1_8_0-openjdk-devel</CODE></PRE><BR /> <H4 id="toc-hId--382343590">To test:</H4><BR /> <P style="margin: 0in;font-family: Calibri;font-size: 11.0pt">Run Command:</P><BR /> <BR /> <BLOCKQUOTE><BR /> <P style="margin: 0in;font-family: Calibri;font-size: 11.0pt">java -version</P><BR /> </BLOCKQUOTE><BR /> <P style="margin: 0in;font-family: Calibri;font-size: 11.0pt">Run Command:</P><BR /> <BR /> <BLOCKQUOTE><BR /> <P style="margin: 0in;font-family: Calibri;font-size: 11.0pt">javac</P><BR /> </BLOCKQUOTE><BR /> If they didn't return any error, you are good to go.<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--707939814">Nano</H3><BR /> This step is entirely optional. I need an editor in linux, and I like to use nano. You can use whatever you like such as vi.<BR /> <H4 id="toc-hId--1273087695">To install</H4><BR /> Run Command:<BR /> <PRE class="language-javascript"><CODE>wget <A href="https://download.opensuse.org/repositories/openSUSE:/Leap:/15.1/standard/x86_64/nano-2.9.6-lp151.2.3.x86_64.rpm" target="test_blank" rel="nofollow noopener noreferrer">https://download.opensuse.org/repositories/openSUSE:/Leap:/15.1/standard/x86_64/nano-2.9.6-lp151.2.3.x86_64.rpm</A><BR /> <BR /> sudo rpm -i nano-2.9.6-lp151.2.3.x86_64.rpm</CODE></PRE><BR /> If this link does not work (because I have no control over it, search for somewhere that that might have a nano rpm distribution)<BR /> <BR /> &nbsp;<BR /> <H4 id="toc-hId--1469601200">To test:</H4><BR /> <BLOCKQUOTE>nano &lt;any file&gt;</BLOCKQUOTE><BR /> &nbsp;<BR /> <H4 id="toc-hId--1666114705">To exit:</H4><BR /> <BLOCKQUOTE>Ctrl + X</BLOCKQUOTE><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--1275822196"><SPAN style="text-decoration: underline">Setting up KAFKA</SPAN></H2><BR /> <H3 id="toc-hId--1765738708">Install</H3><BR /> Run Command:<BR /> <PRE class="language-javascript"><CODE>curl -O <A href="http://apache.mirror.amaze.com.au/kafka/2.4.1/kafka_2.12-2.4.1.tgz" target="test_blank" rel="nofollow noopener noreferrer">http://apache.mirror.amaze.com.au/kafka/2.4.1/kafka_2.12-2.4.1.tgz</A><BR /> <BR /> tar -xvf kafka_2.12-2.4.1.tgz<BR /> <BR /> rm -rf kafka_2.12-2.4.1.tgz<BR /> <BR /> sudo ln -s ~/kafka_2.12-2.4.1 /opt/kafka</CODE></PRE><BR /> &nbsp;<BR /> <H4 id="toc-hId-2039312076">Let's explain</H4><BR /> The script will first go to <A href="https://kafka.apache.org/downloads" target="_blank" rel="nofollow noopener noreferrer">Apache</A> and download KAFKA. If the link in the above command does not work, then change it to the latest from Apache.<BR /> <BR /> The EC2 instance will download KAFKA tgz file, untar it and we create a symbolic link /opt/kafka to the decompressed kafka directory.<BR /> <BR /> That's it... now KAKFA is installed!<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId-2136201578">Configure</H3><BR /> We are going with the most basic configuration/setup here, with single zookeeper, single KAFKA server. It's up to you to explore more complex setup.<BR /> <BR /> Now I'm going to refer to the Apache <A href="https://kafka.apache.org/quickstart" target="_blank" rel="nofollow noopener noreferrer">quick start guide</A> since I can't explain it any better and there's no point of me repeating either.<BR /> <BR /> In short, we are going setup one zoo keeper (on port 2181), one KAFKA server (on port 9092).&nbsp; Remember these ports as you will see code referring to them later.<BR /> <BR /> I run the following script to start the zookeeper and KAFKA server. You need to repeat this after each restart.<BR /> <PRE class="language-java"><CODE>#!/bin/bash<BR /> export KAFKA_HOME="/opt/kafka"<BR /> export KAFKA_HEAP_OPTS="-Xmx512M -Xms256M"<BR /> nohup sudo $KAFKA_HOME/bin/zookeeper-server-start.sh $KAFKA_HOME/config/zookeeper.properties &gt; /dev/null 2&gt;&amp;1 &amp;<BR /> sleep 2<BR /> nohup $KAFKA_HOME/bin/kafka-server-start.sh $KAFKA_HOME/config/server.properties &gt; /dev/null 2&gt;&amp;1 &amp;<BR /> sleep 2</CODE></PRE><BR /> Note that I set the KAFKA heap to be smaller as the EC2 instance struggled with the default memory settings.<BR /> <BR /> Remember to chmod it to execute.<BR /> <BLOCKQUOTE>chmod +x kafka_start.sh</BLOCKQUOTE><BR /> <A href="https://github.com/joymike/sap_kafka_demo/tree/master/1.%20kafka%20startup%20script" target="_blank" rel="nofollow noopener noreferrer">See code here</A><BR /> <H4 id="toc-hId-1646285066">Create a topic:</H4><BR /> I'm going to create a topic "my-kafka-topic". You can call it whatever you want. <SPAN style="text-decoration: underline">You only need to do this once.</SPAN> If you get an error it means your zookeeper or KAFKA server is not started properly.<BR /> <PRE class="language-javascript"><CODE>/opt/kafka/bin/kafka-topics.sh --create --topic my-kafka-topic --zookeeper localhost:2181 --partitions 1 --replication-factor 1</CODE></PRE><BR /> &nbsp;<BR /> <H3 id="toc-hId-1743174568">Test it</H3><BR /> <H4 id="toc-hId-1253258056">Produce a message</H4><BR /> <PRE class="language-javascript"><CODE>/opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-kafka-topic<BR /> </CODE></PRE><BR /> &nbsp;<BR /> <H4 id="toc-hId-1224928242">Consume the message</H4><BR /> In another SSH session, run this:<BR /> <PRE class="language-javascript"><CODE>/opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-kafka-topic --from-beginning</CODE></PRE><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId-1615220751">Setting up SAP JCo</H2><BR /> <SPAN style="text-decoration: underline"><STRONG>Make sure you get JCo 3.0 and not 3.1</STRONG></SPAN><BR /> <BR /> I paid a hefty price of trying to get version 3.1 to work, only to wasted hours on trying to fix a ARPCRFC fast serialization error. So I'm going to use version 3.0 here<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId-1125304239">Where to download</H3><BR /> <A href="https://support.sap.com/en/product/connectors/jco.html" target="test_blank" rel="noopener noreferrer">https://support.sap.com/en/product/connectors/jco.html</A><BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId-928790734">Install</H3><BR /> <H4 id="toc-hId-438874222">Transfer and unzip the file to the EC2 instance</H4><BR /> I suggest you download the "sapjco30P_20-10005328.zip" file first in your desktop and upload it to the EC2 instance. I suggest you either put it somewhere public on the internet and use "wget" or "curl" in the SSH terminal to download. I put it in an S3 bucket and use AWS CLI commands to retrieve it - do whatever works for you.<BR /> <BR /> After the file is on the server, you should unzip it to the folder sapjco30.<BR /> <BR /> &nbsp;<BR /> <PRE class="language-javascript"><CODE>mkdir sapjco30<BR /> cd sapjco30<BR /> aws s3 cp s3://&lt;my-s3-bucket&gt;/sapjco30P_20-10005328.zip sapjco30P_20-10005328.zip<BR /> unzip sapjco30P_20-10005328.zip<BR /> tar -xvf sapjco30P_20-10005328.tgz</CODE></PRE><BR /> If you are not using S3 bucket for transfer, skip the s3 line.<BR /> <BR /> That's it. SAP Java Connector is ready to be used!<BR /> <BR /> Your directory should look like this.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/sap-jco-directory-1.png" /></P><BR /> &nbsp;<BR /> <BR /> Now let's get the simple JCo Server to work. JCo server is basically the receiver of an RFC calls from any NW system. You need to first register this "JCo Server" with the SAP system, kind of like a handshake, so that the NW system knows where to call.<BR /> <BR /> &nbsp;<BR /> <H4 id="toc-hId-242360717">Create RFC Destination</H4><BR /> <TABLE style="border-collapse: collapse;width: 100%" border="1"><BR /> <TBODY><BR /> <TR style="height: 14px"><BR /> <TD style="width: 50%;height: 14px">Name</TD><BR /> <TD style="width: 50%;height: 14px">ZMP_JCO_SERVER</TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 50%;height: 14px">Type</TD><BR /> <TD style="width: 50%;height: 14px">T</TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 50%;height: 14px">Program ID</TD><BR /> <TD style="width: 50%;height: 14px">ZMP_JCO_SERVER</TD><BR /> </TR><BR /> <TR style="height: 14px"><BR /> <TD style="width: 50%;height: 14px">Activation type</TD><BR /> <TD style="width: 50%;height: 14px">Registered Server Program</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/sm59-1.png" /></P><BR /> &nbsp;<BR /> <H4 id="toc-hId-45847212">Test the RFC Destination</H4><BR /> <P style="overflow: hidden;margin-bottom: 0px">It should return an error for now... don't worry... it will work later on.</P><BR /> The error means it can't connect to the JCo server.<BR /> <BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/sm59-connection_test_error.png" /><BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId-142736714">Configure the JCo Server</H3><BR /> I'm going to use the stock standard JCo Server example provided by SAP. You can make this a lot more complex and scalable and performant.<BR /> <H4 id="toc-hId--347179798">Create the JCo Destination file</H4><BR /> <EM>This bit took me hours to figure out, as I couldn't find any documentation that explains this. Perhaps it is straight forward. Standard HTML documentation that comes with the zip file shows you the code and assume you to know how to run it.</EM><BR /> <BR /> <EM>This tells the JCo Server code where our SAP system is. The JCo Server will use this to call SAP system to register a program ID. </EM><BR /> <UL><BR /> <LI>EXT_SERVER.jcoServer</LI><BR /> </UL><BR /> <PRE class="language-javascript"><CODE>#A sample confidguration for a standard registered server <BR /> #Replace the dummy values and put this file in the working directory.<BR /> #In eclipse environment it is the project root directory.<BR /> jco.server.connection_count=2<BR /> jco.server.gwhost=localhost<BR /> jco.server.progid=ZMP_JCO_SERVER<BR /> jco.server.gwserv=sapgw00<BR /> jco.server.repository_destination=ABAP_AS1</CODE></PRE><BR /> Make sure you enter the same program Id as the RFC destination file.<BR /> <BR /> For the registration, the ABAP_AS1 is required as the JCo server makes a call to SAP.<BR /> <BR /> &nbsp;<BR /> <UL><BR /> <LI>ABAP_AS1.jcoDestination</LI><BR /> </UL><BR /> <PRE class="language-javascript"><CODE>#Sample destination configuration when using an application server over CPIC<BR /> #Replace the dummy values and put this file in the working directory.<BR /> #In eclipse environment it is the project root directory.<BR /> jco.client.ashost=vhcalnplci<BR /> jco.client.sysnr=00<BR /> jco.client.client=&lt;sap client&gt;<BR /> jco.client.user=&lt;sap user&gt;<BR /> jco.client.passwd=&lt;sap password&gt;<BR /> jco.client.lang=en <BR /> </CODE></PRE><BR /> Change your ashost to the server name. localhost might work, haven't tried.<BR /> <BR /> &nbsp;<BR /> <H4 id="toc-hId--543693303">Compile the jco server example:</H4><BR /> Edit the StepByStepServer.java file that comes with the Jco zip file.<BR /> <BR /> Configure the server name to be the name of your file.<BR /> <BR /> DESTINATION_NAME=Program ID of RFC Destination.<BR /> <PRE class="language-abap"><CODE> static String SERVER_NAME1 = "EXT_SERVER";<BR /> static String DESTINATION_NAME1 = "ZMP_JCO_SERVER";</CODE></PRE><BR /> Comment out these lines.<BR /> <PRE class="language-abap"><CODE> public static void main(String[] a)<BR /> {<BR /> step1SimpleServer();<BR /> // step2SimpleServer();<BR /> // step3SimpleTRfcServer();<BR /> // step4StaticRepository();<BR /> }</CODE></PRE><BR /> &nbsp;<BR /> <H4 id="toc-hId--572023117">Run</H4><BR /> <PRE class="language-javascript"><CODE>javac -cp ~/sapjco30/sapjco3.jar:/opt/kafka/libs/* StepByStepServer.java<BR /> <BR /> java -cp ~/sapjco30/sapjco3.jar:/opt/kafka/libs/*:. StepByStepServer</CODE></PRE><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/jco-server-start.png" /></P><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--475133615">Test it</H3><BR /> <H4 id="toc-hId--965050127">Test the RFC destination</H4><BR /> <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/sm59-connection_test.png" /><BR /> <BR /> It's working!<BR /> <H4 id="toc-hId--1161563632">Test the function module</H4><BR /> Go to transaction SE37 and call function STFC_CONNECTION with the RFC destination.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/jco-server-test.png" /></P><BR /> The call is successful. The Java code response with "Hello World".<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/jco-server-test-result-1.png" /></P><BR /> The call is successfully received by the JCo Server.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/jco-server-test-result-2.png" /></P><BR /> &nbsp;<BR /> <BR /> Finally, all the bits and bobs are set up... Now... back to why we are trying to do this, we want to be able for ABAP to call a java program using Java Connector, and produce a message on KAFKA... See Part 3. 2020-04-14T14:12:29+02:00 https://community.sap.com/t5/technology-blogs-by-members/produce-consume-messages-in-kafka-with-sap-netweaver-using-java-connector/ba-p/13433087 Produce/consume messages in KAFKA with SAP Netweaver using Java Connector – Part 3/3 2020-04-15T00:36:31+02:00 michael_pang4 https://community.sap.com/t5/user/viewprofilepage/user-id/245249 This is the final part of my blog.... we are now going to join the dots together.<BR /> <BR /> The funny thing with doing a proof of concept on AWS is like getting a taxi ride... every minute counts... <span class="lia-unicode-emoji" title=":slightly_smiling_face:">🙂</span><BR /> <BR /> Let's recap.<BR /> <BR /> &nbsp;<BR /> <BR /> We now have an EC2 instance running in AWS with:<BR /> <UL><BR /> <LI>SAP NW backend</LI><BR /> <LI>RFC destination setup</LI><BR /> <LI>KAFKA setup and we can produce and consume messges from a topic "my-kafka-topic"</LI><BR /> <LI>SAP JCo Server setup and connection established with the SAP NW</LI><BR /> </UL><BR /> &nbsp;<BR /> <BR /> Now, back to the fun part.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId-931599261">Produce a message from SAP to KAFKA</H2><BR /> I copied the Java code from "Tutorialspoint.com" and put it inside StepByStepServer.java provided by SAP. See SimpleProducer.java from <A href="https://www.tutorialspoint.com/apache_kafka/apache_kafka_simple_producer_example.htm" target="test_blank" rel="nofollow noopener noreferrer">https://www.tutorialspoint.com/apache_kafka/apache_kafka_simple_producer_example.htm</A><BR /> <BR /> (I will not take credit for this code.)<BR /> <H3 id="toc-hId-864168475">Compile and run the code</H3><BR /> <A href="https://github.com/joymike/sap_kafka_demo/tree/master/3.%20sap-kafka-producer" target="_blank" rel="nofollow noopener noreferrer">See code here</A><BR /> <BR /> You need the following files:<BR /> <UL><BR /> <LI>ABAP_AS1.jcoDestination</LI><BR /> <LI>EXT_SERVER.jcoServer</LI><BR /> <LI><A href="https://github.com/joymike/sap_kafka_demo/blob/master/3.%20sap-kafka-producer/StepByStepServer.java" target="_blank" rel="nofollow noopener noreferrer">StepByStepServer.java</A></LI><BR /> </UL><BR /> Now this StepByStepServer.java file is a combination of the SAP example "StepByStepServer.java" and some code I copied from <A href="https://www.tutorialkart.com/apache-kafka/" target="_blank" rel="nofollow noopener noreferrer">here</A>. I didn't spend too much time on making the code pretty and neat. I just did the necessary to make it work so please don't judge.<BR /> <H3 id="toc-hId-667654970">What did I change in StepByStepServer.java:</H3><BR /> <PRE class="language-abap"><CODE> static String SERVER_NAME1 = "EXT_SERVER";<BR /> static String DESTINATION_NAME1 = "ZMP_JCO_SERVER";</CODE></PRE><BR /> In the handleRequest method, I added the following:<BR /> <PRE class="language-java"><CODE> String message = function.getImportParameterList().getString("REQUTEXT");<BR /> <BR /> // Assign topicName to string variable<BR /> String topicName = "my-kafka-topic";<BR /> <BR /> // create instance for properties to access producer configs<BR /> Properties props = new Properties();<BR /> // Assign localhost id<BR /> props.put("bootstrap.servers", "localhost:9092");<BR /> // Set acknowledgements for producer requests.<BR /> props.put("acks", "all");<BR /> // If the request fails, the producer can automatically retry,<BR /> props.put("retries", 0);<BR /> // Specify buffer size in config<BR /> props.put("batch.size", 16384);<BR /> // Reduce the no of requests less than 0<BR /> props.put("linger.ms", 1);<BR /> // The buffer.memory controls the total amount of memory available to the<BR /> // producer for buffering.<BR /> props.put("buffer.memory", 33554432);<BR /> props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");<BR /> props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");<BR /> producer = new KafkaProducer&lt;String, String&gt;(props);<BR /> producer.send(new ProducerRecord&lt;String, String&gt;(topicName, message, message));<BR /> function.getExportParameterList().setValue("RESPTEXT", "Message sent successfully");<BR /> System.out.println("Message sent successfully");<BR /> // producer.close();​</CODE></PRE><BR /> What the code does is take the text passed from the STFC_CONNECTION function module, and call the Apache KAFKA producer API with it. It's that simple.<BR /> <BR /> Compile and run. Notice I need to put both JCo and KAFKA libraries in the classpath now.<BR /> <PRE class="language-javascript"><CODE>export KAFKA_HEAP_OPTS="-Xmx512M -Xms256M"<BR /> javac -cp ~/sapjco30/sapjco3.jar:/opt/kafka/libs/* StepByStepServer.java</CODE></PRE><BR /> &nbsp;<BR /> <H3 id="toc-hId-471141465">Run the JCo Server</H3><BR /> <PRE class="language-javascript"><CODE>java -cp ~/sapjco30/sapjco3.jar:/opt/kafka/libs/*:. StepByStepServer</CODE></PRE><BR /> <H3 id="toc-hId-274627960">Start KAFKA consumer</H3><BR /> <PRE class="language-javascript"><CODE>/opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-kafka-topic</CODE></PRE><BR /> &nbsp;<BR /> <H3 id="toc-hId-78114455">Call RFC function module</H3><BR /> <H3 id="toc-hId--118399050"></H3><BR /> <H3 id="toc-hId--314912555">Result</H3><BR /> Here's a link to the youtube video for the result<BR /> <BR /> <A href="https://youtu.be/giAMdDeKUs0" target="test_blank" rel="nofollow noopener noreferrer">https://youtu.be/giAMdDeKUs0</A><BR /> <BR /> <IFRAME width="560" height="315" src="https://www.youtube.com/embed/giAMdDeKUs0&amp;feature=youtu.be" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></IFRAME><BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId--640508779">Consume a message using the Java connector client and call RFC</H2><BR /> Now let's try the other way. Someone changed a transaction outside and published to a KAFKA topic and SAP wants to know about it and do something with it.<BR /> <BR /> &nbsp;<BR /> <BR /> The flow is:<BR /> <OL><BR /> <LI>Message is produced to KAFKA topic</LI><BR /> <LI>Java client (with Java Connector) consumes the message.</LI><BR /> <LI>Java client calls SAP RFC</LI><BR /> <LI>SAP RFC do something with the message.</LI><BR /> </OL><BR /> &nbsp;<BR /> <BR /> I copied the Java code from "Tutorialspoint.com" and put it inside StepByStepServer.java provided by SAP. See SimpleProducer.java from <A href="https://www.tutorialspoint.com/apache_kafka/" target="test_blank" rel="nofollow noopener noreferrer">https://www.tutorialspoint.com/apache_kafka/</A><BR /> <BR /> (I will not take credit for this code.)<BR /> <H3 id="toc-hId--707939565">Setup and run the JCo Client</H3><BR /> <A href="https://github.com/joymike/sap_kafka_demo/tree/master/4.%20sap-kafka-consumer" target="_blank" rel="nofollow noopener noreferrer">See code here</A><BR /> <BR /> You need the following files:<BR /> <UL><BR /> <LI>ABAP_AS1.jcoDestination</LI><BR /> <LI><A id="3469f1fdb23d0d7fa0421cab47c2323f-77521d240ba5943d8696f90be451a5dc5563b473" class="js-navigation-open " title="SapKafkaConsumer.java" href="https://github.com/joymike/sap_kafka_demo/blob/master/4.%20sap-kafka-consumer/SapKafkaConsumer.java" target="_blank" rel="nofollow noopener noreferrer">SapKafkaConsumer.java</A></LI><BR /> <LI><A id="1ef51d7189a82c90b45f904331d3dc02-1f9cd9cafdbeab1050e7a403cef599527a6fa466" class="js-navigation-open " title="SapKafkaConsumerDemo.java" href="https://github.com/joymike/sap_kafka_demo/blob/master/4.%20sap-kafka-consumer/SapKafkaConsumerDemo.java" target="_blank" rel="nofollow noopener noreferrer">SapKafkaConsumerDemo.java</A></LI><BR /> </UL><BR /> Now let's explain.<BR /> <BR /> <A id="3469f1fdb23d0d7fa0421cab47c2323f-77521d240ba5943d8696f90be451a5dc5563b473" class="js-navigation-open " title="SapKafkaConsumer.java" href="https://github.com/joymike/sap_kafka_demo/blob/master/4.%20sap-kafka-consumer/SapKafkaConsumer.java" target="_blank" rel="nofollow noopener noreferrer">SapKafkaConsumer.java</A> is a copy of the SimpleConsumer.java which I borrowed from <A href="https://www.tutorialspoint.com/apache_kafka/" target="_blank" rel="nofollow noopener noreferrer">here </A>&nbsp;as mentioned, combined with the code from the StepByStepClient.java from the SAP example.<BR /> <BR /> The code can already consume a message from a KAFKA topic "my-kafka-topic", and I take that message and call function STFC_CONNECTION in SAP with the message.<BR /> <BR /> The function will echo back the text showing it has successfully received it.<BR /> <BR /> &nbsp;<BR /> <BR /> In the doWork method which is called when a message is received, I've added the code to call function STFC_CONNECTION. It should be straight forward what the code does.<BR /> <H4 id="toc-hId--1273087446"></H4><BR /> <H4 id="toc-hId--1469600951">Compile and run the Java client</H4><BR /> <PRE class="language-abap"><CODE>javac -cp ~/sapjco30/sapjco3.jar:/opt/kafka/libs/* -Xlint:deprecation *.java<BR /> java -cp ~/sapjco30/sapjco3.jar:/opt/kafka/libs/*:. SapKafkaConsumeDemo</CODE></PRE><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <H3 id="toc-hId--1372711449">Produce a message to KAFKA topic</H3><BR /> <PRE class="language-javascript"><CODE>/opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-kafka-topic</CODE></PRE><BR /> &nbsp;<BR /> <H3 id="toc-hId--1569224954">Results</H3><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/Client-producer-1.png" /></P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/04/Client-consumer-sapjco.png" /></P><BR /> Voila.<BR /> <BR /> &nbsp;<BR /> <BR /> Here's a youtube video.<BR /> <BR /> <IFRAME width="560" height="315" src="https://www.youtube.com/embed/2XtHmhM18UE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen=""></IFRAME><BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> In summary, it is possible and also not too difficult to do so.<BR /> <BR /> What we now need to explore is how to productionize this solution, how to make this HA/DR etc. I'm still have some unanswered questions on how this can handle massive volume in an enterprise environment, or whether the JCo server and client should be on a separate instance.<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> Anyway, thanks for you time, I hope you find this interesting. Leave me some comments below. 2020-04-15T00:36:31+02:00 https://community.sap.com/t5/technology-blogs-by-members/big-data-integration-of-sap-netweaver-using-i-ohja/ba-p/13434740 Big Data integration of SAP Netweaver using i-OhJa 2020-05-05T12:19:53+02:00 ronald_schertle https://community.sap.com/t5/user/viewprofilepage/user-id/595539 <H1 id="toc-hId-802552929">Introduction</H1><BR /> In this blog post I want to share some ideas and experiences with implementing a component using SAP <STRONG>J</STRONG>ava <STRONG>Co</STRONG>nnector to easily access data and integrate non-SAP processes like data pipelines in big data clusters with the SAP Netweaver Application Server. This finally led to our solution called i-OhJa.<BR /> <BR /> About two years ago we started working on a project for some customer in the financial sector. The main task was to set up a Hadoop stack as the new company wide BI platform for big data and streaming. One requirement in the migration phase was to stage load data from SAP BW (on Oracle) to Kafka, another one to load data from Kafka to BW in streaming mode. During this time Kafka streams was out of scope, so we decided to implement our dataflows in Spark streaming. This was the first project to run i-OhJa on customer side in a Spark cluster.<BR /> <BR /> Prior to the project we already started evaluating SAP JCo as a library not only providing a JDBC driver for databases in a SAP Netweaver system, but being able to tightly integrate SAP and non-SAP applications in a flexible way. Our goal for i-OhJa was to implement a thin library that meets the requirements mentioned above in a highly regulated sector of financial institutions, without the need to introduce new complex infrastructures or clusters. JCo being a mighty but also basic Java library with the ability to establish a trusted and encrypted connection to SAP Netweaver systems using SNC and SSO provided by the SAP Cryptolib was the best fit for this scenario.<BR /> <BR /> To be honest, the last time I implemented software in Java and J2EE using Eclipse IDE was back in 2008. After a long period mostly utilizing ABAP in SAP Netweaver based systems, I was pleased to use a more modern IDE and a functional and type safe language like Scala as our choice for developing i-OhJa. In the above-mentioned scenario, we chose to use SAP BW Open Hubs and SAP Netweaver events to get data out of BW. For the opposite direction we used Webservice DataSources to load data into BW in a streaming and real-time manner. All these interfaces are based on RFC enabled function modules and have a tight integration into the monitoring and scheduling environment of SAP BW.<BR /> <H1 id="toc-hId-606039424">EL(T)</H1><BR /> Since there are already a bunch of ETL tools out there and as we wanted to keep i-OhJa as thin as possible, we decided to cover only the <STRONG>E</STRONG>xtraction and <STRONG>L</STRONG>oad of ELT. This also follows some basic ideas of modern microservice architectures. In the scenarios mentioned above this means that the data held in Kafka is a close replication of the data being transferred via OpenHub or Webservice DataSource.<BR /> <H1 id="toc-hId-409525919">Type safety and wrappers</H1><BR /> A thing we like most about Scala besides its functional style is keeping our code type safe. A short time after starting to implement i-OhJa we decided to wrap all necessary JCo classes in Scala classes for being able to use them natively in e.g. pattern matching and collection functions and providing type safety and immutability. We provide class wrappers for function templates, function requests, function responses, tables, records/structures, record fields, all elementary types available in JCo 3.1, parameter lists, corresponding meta data classes of JCo, DDIC types, message types, selection ranges, aggregation functions, ABAP exceptions, JCo destinations, BAPI return messages, BAPI transaction commit and rollback in JCo context and more.<BR /> <H1 id="toc-hId-213012414">Code generation</H1><BR /> With one of our customers we saw customer specific ELT frameworks written in Scala using JSON-like configuration files to define individual data pipelines. Concepts following this dynamic principle have some drawbacks:<BR /> <UL><BR /> <LI>The configuration files need to be parsed with every execution of the batch or streaming pipeline</LI><BR /> <LI>Issues in the configuration files besides syntactic correctness lead to runtime exceptions because they bypass type checks of the compiler.</LI><BR /> <LI>The ELT framework implementation makes heavy use of methods like <EM>asInstanceOf</EM> and <EM>isInstanceOf</EM> to cope with the vast amount of different interface data structures and types. As all the ELT logic is kept in configuration files the individual data types are known as soon as these files are being parsed, which is at runtime of the pipelines.</LI><BR /> <LI>Using configuration files to define pipelines makes them more flexible. They can be changed and maintained without the need to change the underlying code. Therefore, the changes don’t need to be recompiled and you don’t have to follow the build and release cycle of the customer.<BR /> We consider this approach as a drawback here. Changes to configuration files are comparable to code changes bypassing all the code checks and quality gates implemented in your continuous integration processes.</LI><BR /> </UL><BR /> Us being supporters of static type safety, we decided to take a different approach to handle the challenge of diverse data structures. We implemented Scala code generators producing case classes representing the structure of individual RFC function modules.<BR /> An example of the generated classes for a simple BAPI like BAPI_ODSO_GETLIST, delivering a list of available DSOs in a SAP BW system, would look like this:<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/image001.png" /></P><BR /> <BR /> <PRE><CODE>case class JCoBapiOdsoGetlistWrapper(<BR /> &nbsp;&nbsp;&nbsp; importing: JCoBapiOdsoGetlistWrapper.Importing = JCoBapiOdsoGetlistWrapper.<EM>Importing</EM>(),<BR /> &nbsp;&nbsp;&nbsp; exporting: JCoBapiOdsoGetlistWrapper.Exporting = JCoBapiOdsoGetlistWrapper.<EM>Exporting</EM>(),<BR /> &nbsp;&nbsp;&nbsp; changing: JCoBapiOdsoGetlistWrapper.Changing = JCoBapiOdsoGetlistWrapper.<EM>Changing</EM>(),<BR /> &nbsp;&nbsp;&nbsp; tables: JCoBapiOdsoGetlistWrapper.Tables) extends JCoBapiOdsoGetlistWrapper.JCoFunctionWrapper {…}<BR /> <BR /> case class Importing(objvers: Option[Char] = Some('R')) extends JCoParametersWrapper {…}<BR /> <BR /> case class Exporting(`return`: Exporting.Return = Exporting.Return()) extends JCoParametersWrapper {…}<BR /> case class Changing() extends JCoParametersWrapper {…}<BR /> <BR /> case class Tables(<BR /> &nbsp;&nbsp;&nbsp; odsobjectlist: Seq[Tables.Odsobjectlist] = <EM>Nil</EM>,<BR /> &nbsp;&nbsp;&nbsp; selodsobject: Seq[Tables.Selodsobject] = <EM>Nil</EM>,<BR /> &nbsp;&nbsp;&nbsp; seltextlong: Seq[Tables.Seltextlong] = <EM>Nil</EM>) extends JCoParametersWrapper {…}<BR /> <BR /> case class Return(<BR /> &nbsp;&nbsp;&nbsp; `type`: Option[Char] = None,<BR /> &nbsp;&nbsp;&nbsp; id: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; number: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; message: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; logNo: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; logMsgNo: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; messageV1: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; messageV2: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; messageV3: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; messageV4: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; parameter: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; row: Option[Int] = None,<BR /> &nbsp;&nbsp;&nbsp; field: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; system: Option[String] = None) extends JCoRecordWrapper {…}<BR /> <BR /> case class Odsobjectlist(<BR /> &nbsp;&nbsp;&nbsp; odsobject: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; objvers: Option[Char] = None,<BR /> &nbsp;&nbsp;&nbsp; textlong: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; objstat: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; activfl: Option[Char] = None,<BR /> &nbsp;&nbsp;&nbsp; infoarea: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; odsotype: Option[Char] = None) extends JCoRecordWrapper {…}<BR /> <BR /> case class Selodsobject(<BR /> &nbsp;&nbsp;&nbsp; sign: Option[Char] = None,<BR /> &nbsp;&nbsp;&nbsp; option: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; odsobjectlow: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; odsobjecthigh: Option[String] = None) extends JCoRecordWrapper {…}<BR /> <BR /> case class Seltextlong(<BR /> &nbsp;&nbsp;&nbsp; sign: Option[Char] = None,<BR /> &nbsp;&nbsp;&nbsp; option: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; textlonglow: Option[String] = None,<BR /> &nbsp;&nbsp;&nbsp; textlonghigh: Option[String] = None) extends JCoRecordWrapper {…}</CODE></PRE><BR /> <H1 id="toc-hId-16498909">Client and server</H1><BR /> JCo consists of two types of library components: JCo server and JCo client. For now, it is enough to know that JCo Server will be used in cases where SAP Netweaver ABAP initiates communication (here: OpenHub scenario). Whereas JCo client is used if non-SAP applications make calls to RFCs (here: Webservice DataSource push).<BR /> <H2 id="toc-hId--50931877">BW and ODP specific client libraries</H2><BR /> For interfaces, protocols and function libraries that are more complex than just calling one single RFC function module, it makes sense to provide specific client library modules.<BR /> <BR /> We have done so for the good old BW OpenHub connections, BW BAPIs and Operational Data Provisioning. As one might expect all these interfaces are based on plain RFC functions, even ODPs as successor of the business content DataSources, which were based on ALE/IDocs.<BR /> <BR /> A challenge you will face when querying data through generic interfaces like OpenHubs, BW BAPIs or ODPs serving different kind of data structures is that data is serialized as text encoded strings with a record being a concatenation of different data types in a single string. An obvious option to reconstruct data structures would be to parse these strings directly into native Java or Scala objects. We took an alternative approach by parsing the strings into wrapped JCo structures created on the fly based on the meta information we get from the corresponding function modules. This way we use JCo to convert the strings into proper data types and we can afterwards make use of all the methods provided by i-OhJa for the respective wrapper classes.<BR /> <BR /> JCo allows creating JCoStructure and JCoTable objects based on JCoRecordMetaData objects. In a normal use case one would get these meta data objects by querying the repository, but in this scenario the structures need to be built at runtime by making use of the <EM>JCo.createRecordMetaData</EM> method. A challenge we faced was providing byte lengths, offsets and alignments to the <EM>JCoRecordMetaData.add</EM> methods for all the data types a field of a structure can have. i-OhJa offers the ability to calculate the byte offsets and lengths for all JCo type wrappers. Together with conversion methods for all the different DDIC and InfoObject types it can create structures and even whole JCoFunction instances based on different kind of metadata.<BR /> <H2 id="toc-hId--247445382">Reactive OpenHub server using Akka</H2><BR /> For being able to listen for new incoming data and requests i-OhJa provides a server component with services wrapped around JCo server. Services have to extend a defined service trait and have to implement the logic for listening and processing incoming requests from a SAP system. They can also make use of the i-OhJa client libraries to request data from the SAP system. The services can be provided at runtime by registering to an i-OhJa server instance. Some predelivered services like the OpenHub extraction provide another interface for being able to register so called data adapters. The services will pass the processed data to the registered data adapter that contains the logic to finally pass or store the data. Predelivered data adapters for the OpenHub service can store data in a CSV file, output data in the console or publish data to a Kafka topic in a Kafka cluster. Further services or data adapters can be implemented according to customer specific requirements.<BR /> <BR /> For being able to react fast on incoming requests, a dispatcher instance forwards requests instantly to the corresponding services. The OpenHub service uses Akka to process several OpenHub request-packages asynchronously and in parallel. A backpressure algorithm takes care of in-/decreasing the amount of data packages extracted and processed in parallel according to the resources being available.<BR /> <H1 id="toc-hId--573041606">Converters and SerDe</H1><BR /> A typical scenario in JCo applications is to register a destination provider before using a destination object to retrieve a function object from the repository. This mutable function object contains all meta data of the corresponding RFC function module together with the state of parameter values and exceptions before and after calling the function module. In short, this object contains all the information we send to and get back from the Netweaver system using function modules.<BR /> In several cases you will have the need to serialize this object or parts of it, e.g. when sending data to Kafka or storing RFC responses for use in unit tests. Another advantage of serializing function objects is that after storing a serialized RFC response you don’t need an active SAP connection anymore to create function objects. This is an alternative to using JCo function templates, which are supported by i-OhJa too.<BR /> You can serialize a function object easily by using native Java serialization with several drawbacks, like not being able to deserialize it when upgrading JCo versions and so on. But this was only one reason for us to implement (de-)serialization using different kind of data formats.<BR /> <BR /> So far, we have implemented and used converters and SerDes for the following data formats:<BR /> <UL><BR /> <LI>i-OhJa Scala wrappers and case classes from JCo Java classes:<BR /> For all the converters and SerDes implemented, i-OhJa provides implicit Scala conversion classes that just need to be imported in your application code. JCo is completely and transparently hidden behind the corresponding Scala wrappers and you do not have to worry about internal conversion and usage of JCo.</LI><BR /> <LI>JSON:<BR /> The JSON SerDe provides lossless bidirectional serialization and deserialization holding data values and types in the same structure. We recommend the use of JSON as serialization format e.g. for RFC function templates, so you will be able to store the interface definition of common RFC enabled function modules or BAPIs provided by SAP Netweaver systems in a human readable way.</LI><BR /> <LI>Avro 1.9.2:<BR /> Avro is widely used when it comes to serialization in big data systems like Kafka. It was our first choice for serializing data coming from SAP in the scenarios mentioned in the introduction. It supports all the data types we need like deep structures and separates the schema definition from the actual serialized data. i-OhJa can be used to apply lossless bidirectional serialization and deserialization using Avro. The generated schema definition can be used to e.g. include it in the stream of data published to Kafka, it can be stored in a AVSC file or send to a schema registry service.</LI><BR /> <LI>Protobuf v3:<BR /> The Protobuf SerDe uses a fixed schema defined in a .proto file according to the type wrapper classes used to represent RFC requests and responses and all dependent types like records, tables and elementary types.</LI><BR /> <LI>CSV:<BR /> The structure of CSV files only allows to store two-dimensional data like tables, so currently there is only support to serialize tables and records used in function modules in CSV files.</LI><BR /> <LI>Spark:<BR /> Spark structured streaming uses its own schema definition defined in the package <EM>sql</EM>. Data structures can be nested deeply in objects of the class <EM>sql.Row</EM>. Spark includes all data types and schema structures necessary to convert all kind of JCo types into Spark SQL types. i-OhJa includes corresponding conversion methods, which were used when implementing the data pipelines in our customers projects.</LI><BR /> <LI>Kafka connect:<BR /> Kafka connect defines unique schema and data objects for internal use. This allows to apply common data type converters supplied by Confluent to data streams created by diffent kind of source connectors. In a POC we implemented a flexible Kafka connect SAP Netwevaer source connector tested using the debezium embedded engine for use in the Confluent platform.</LI><BR /> <LI>Native object serialization:<BR /> One can use native Scala and Java object serialization for the wrapper classes of i-OhJa or the POJOs that can be extracted from wrapped data.</LI><BR /> </UL><BR /> <H1 id="toc-hId--769555111">UI</H1><BR /> We provide two types of user interfaces for interaction with i-OhJa: A <STRONG>C</STRONG>ommand <STRONG>L</STRONG>ine <STRONG>I</STRONG>nterface and a simple server and client Web UI based on Twirl and Akka HTTP. Akka HTTP is used for building a reactive HTTP server, while Twirl allows to generate HTML pages based on native Scala code. This is an easy way to provide direct access to all kind of Scala based functionality provided by i-OhJa that is wrapped around JCo.<BR /> The following screenshots show basic web pages demonstrating possibilities to monitor and access i-OhJa.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/image002.png" /></P><BR /> <P style="overflow: hidden;margin-bottom: 0px">The Server page is a simple page containing information about registered services and their RFC modules as well as running instances. In the Image shown above you can see the progress of extracting an OpenHub request.</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/image003.png" /></P><BR /> The i-OhJa client page gives an overview of artifacts available in a connected SAP Netweaver system like RFCs, ODPs, OpenHubs and so on.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/image004.png" /></P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/image005.png" /></P><BR /> The page for a SAP BW DataStoreObject gives you an overview of the properties of a DSO and the available fields respectively InfoObjects. One can download the schema of the data in various formats or open a data preview for active data of the DSO for being able to see what the structure of the data being extracted will look like.<BR /> <H1 id="toc-hId--966068616">Testing and mocks</H1><BR /> When it comes to unit testing of interface library functions like the ones contained in i-OhJa, we first must provide server and client mocks for being able to execute local tests without the need to establish a connection to a SAP Netweaver system. This was achieved by extending the wrapped JCo classes like JCoDestination, DestinationDataProvider, ServerDataProvider, JCoServerFactory etc.<BR /> With the mocks in place you just have to implement the behavior of the mocks based on RFC function calls. A simple scala test for the BI client method to retrieve a list of OpenHub objects available in a SAP system 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/2020/05/image006.png" /></P><BR /> This test implementation uses a trace of an RFC call stored in a json file to retrieve the list of OpenHubs without establishing a connection to a SAP system.<BR /> For generating test data, one has basically two options:<BR /> <OL><BR /> <LI>Create a function template object and use generators like the ones from ScalaCheck to fill the parameters of the created function objects with generated values.</LI><BR /> <LI>Trace SAP RFC function calls once, serialize and store them in object files using a SerDe and use these to replay a specific scenario locally without an active connection to a SAP system. This is the scenario we can see in the example provided above.</LI><BR /> </OL><BR /> <H1 id="toc-hId--392842038">Side notes</H1><BR /> <UL><BR /> <LI>Before starting to work with JCo it is worth to know that renaming the JCo-jar leads to a runtime exception because SAP doesn’t allow renaming this file:<BR /> Exception in thread "main" java.lang.ExceptionInInitializerError: JCo initialization failed with java.lang.ExceptionInInitializerError:<BR /> <EM>Illegal JCo archive "sapjco-3.1.2.jar". It is not allowed to rename or repackage the original archive "sapjco3.jar".<BR /> at com.sap.conn.jco.rt.MiddlewareJavaRfc.&lt;clinit&gt;(MiddlewareJavaRfc.java:165)<BR /> at com.sap.conn.jco.rt.DefaultJCoRuntime.initialize(DefaultJCoRuntime.java:78)<BR /> at com.sap.conn.jco.rt.JCoRuntimeFactory.&lt;clinit&gt;(JCoRuntimeFactory.java:23)</EM><BR /> This is an issue when working with local artifactories storing artifacts using the Maven naming conventions. One workaround is to store the native libraries and the jar as a zip-file and configuring local unzipping as part of your POM. Another solution is to provide the path to the native library when starting your application using jvm parameter -Djco.library=".\sapjco-3.1.2.dll". If doing so the jar needs to be stored at the same path as the native library, but you will be able to rename it.</LI><BR /> <LI>When running JCo in a Hortonworks HDP cluster we realized that using <EM> isDestinationDataProviderRegistered()</EM> does not lead to the expected results. This will often return <EM>false</EM>, but if you try to register a destination provider afterwards you will get a runtime exception saying that a destination provider was already registered.</LI><BR /> <LI>An attentive reader might have noticed the default value ‘R’ for the object version in the importing parameter list of the generated code example for BAPI BAPI_ODSO_GETLIST. This seems to be a bug in JCo not being able to resolve parameter default values based on type pool constants like RS_C_OBJVERS-ACTIVE.</LI><BR /> </UL><BR /> <H1 id="toc-hId--589355543">Summary</H1><BR /> SAP JCo and IDoc provide basic APIs for a flexible and extensive interaction with SAP Netweaver application servers. We have implemented i-OhJa as a Scala framework for being able to use SAP JCo in a functional, typesafe and easy way. Furthermore, it simplifies accessing and transforming data transmitted via RFCs. We have successfully utilized it in a Big Data scenario using Apache Spark to integrate streaming pipelines with SAP Netweaver systems. This kind of integration is much more flexible compared to simple JDBC drivers with direct database access and allows to combine any kind of services and processes available in Java and SAP Netweaver based systems. 2020-05-05T12:19:53+02:00 https://community.sap.com/t5/technology-blogs-by-sap/how-to-call-function-modules-using-sap-cloud-sdk-for-java/ba-p/13439653 How to call function modules using SAP Cloud SDK for Java 2020-05-08T07:21:21+02:00 Fukuhara https://community.sap.com/t5/user/viewprofilepage/user-id/44116 Hi All,<BR /> <BR /> I am writing this blog to describe steps to build Java application calling function modules on SAP Cloud Platform CF with SAP Cloud SDK.<BR /> <BR /> Function modules are on on-premise environment and called by JCo via SAP Cloud Connector.<BR /> <BR /> There are so many useful information <A href="https://sap.github.io/cloud-sdk/docs/java/features/bapi-and-rfc/bapi-and-rfc-overview" target="_blank" rel="nofollow noopener noreferrer">here</A>.(2020/8/21 Added)<BR /> <H1 id="toc-hId-802700957">Architecture</H1><BR /> System architecture is as below image, which is on the <A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/bfcb54ca058f4b1dafd26e438ff1e2f4.html" target="_blank" rel="noopener noreferrer">SAP Help portal</A>.<BR /> <BR /> <IMG src="https://help.sap.com/doc/PRODUCTION/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/loiocfadd397cba3494a9261bf1990978bba_LowRes.png" /><BR /> <BR /> It takes time to test this for me, since I was unfamiliar with SAP Cloud Platform services like XSUAA and App Router.&nbsp; To understand SAP Cloud Platform services, I posted <A href="https://blogs.sap.com/2020/05/01/app-router-xsuaa%e3%81%a8java-application%e9%96%8b%e7%99%ba/" target="_blank" rel="noopener noreferrer">an article about App Router, XSUAA and Java Application in Japanese.</A><BR /> <H1 id="toc-hId-606187452">Environment</H1><BR /> I used both Windows and Ubuntu PC, just because my development environment is separated into Java and others.&nbsp; It is not mandatory to use both windows and ubuntu.<BR /> <H2 id="toc-hId-538756666">Local PC(Java development on Windows)</H2><BR /> <UL><BR /> <LI>OS: Windows10 64-bit</LI><BR /> <LI>openJDK: 1.8.0_242</LI><BR /> <LI>Chocolatey: 0.10.15</LI><BR /> <LI>maven: 3.6.3</LI><BR /> <LI>IDE: IntelliJ IDEA Community Edition 2019.3.5</LI><BR /> <LI>CF cli: 6.51.0+2acd15650.2020-04-07</LI><BR /> <LI>SAP Cloud SDK for Java: 3.19.1</LI><BR /> </UL><BR /> <H2 id="toc-hId-342243161">Local PC(App router development on Ubuntu)</H2><BR /> <UL><BR /> <LI>OS: Ubuntu18.04.01 LTS</LI><BR /> <LI>nvm: 0.35.3</LI><BR /> <LI>Node.js: 12.16.2</LI><BR /> <LI>npm: 6.14.5</LI><BR /> <LI>SAP Cloud SDK for JavaScript:1.19.0</LI><BR /> <LI>SAP Cloud SDK cli: 0.1.8</LI><BR /> <LI>CF cli: 6.51.0+2acd15650.2020-04-07</LI><BR /> </UL><BR /> <H2 id="toc-hId-145729656">Cloud Foundry</H2><BR /> <UL><BR /> <LI>Java Buildpack version: sap java build pack 1.25.0</LI><BR /> <LI>CF (Europe – Frankfurt)</LI><BR /> </UL><BR /> <H2 id="toc-hId--50783849">Netweaver ABAP</H2><BR /> <UL><BR /> <LI>NetWeaver ABAP 7.53 SP0</LI><BR /> </UL><BR /> <H2 id="toc-hId--247297354">Cloud Connector</H2><BR /> <UL><BR /> <LI>SAP Cloud Connector 2.11.2</LI><BR /> </UL><BR /> Seeing following stackoverflow question, invoking function modules/ BAPIs from localhost is not supported.<BR /> <BLOCKQUOTE>What you wanna do is technically not supported: You want to invoke a BAPI&nbsp;<I>from your localhost</I>&nbsp;via the transport protocol RFC using the JCo library (used behind the scenes via the SAP Cloud SDK). The usage of JCo requires to run your app on SAP Cloud Platform.</BLOCKQUOTE><BR /> <A href="https://stackoverflow.com/questions/59819607/target-host-is-not-specified-exception-while-calling-bapi-from-java-using-sap-cl" target="_blank" rel="nofollow noopener noreferrer">https://stackoverflow.com/questions/59819607/target-host-is-not-specified-exception-while-calling-bapi-from-java-using-sap-cl</A><BR /> <BR /> I'm not sure if invoking them is possible with Neo SDK.<BR /> <BLOCKQUOTE>when deploying locally you must add a dependency to Neo SDK (which also contains the JCO libraries).</BLOCKQUOTE><BR /> <A href="https://answers.sap.com/questions/13012430/classnotfoundexception-when-calling-remote-functio.html?childToView=13013904#answer-13013904" target="_blank" rel="noopener noreferrer">https://answers.sap.com/questions/13012430/classnotfoundexception-when-calling-remote-functio.html?childToView=13013904#answer-13013904</A><BR /> <H1 id="toc-hId--572893578">Steps</H1><BR /> <H2 id="toc-hId--640324364">1. Setup Cloud Connector</H2><BR /> Access SAP Cloud Connector and setup connection from SAP Cloud Platform to ABAP Server.&nbsp; The steps are same as the one of&nbsp; <A href="https://blogs.sap.com/2020/05/07/configure-cloud-connector-for-rfc-connection-from-cloud-to-on-premise/" target="_blank" rel="noopener noreferrer">blog post "Configure Cloud Connector for RFC connection from cloud to on-premise".</A><BR /> <H2 id="toc-hId--836837869">2. Create Destination</H2><BR /> Create Destination service by&nbsp;<A href="http://cli.cloudfoundry.org/en-US/cf/create-service.html" target="_blank" rel="nofollow noopener noreferrer">CF cli command “cf create-service”</A>.&nbsp; “lite” is service plan name.&nbsp; The steps are same as the one of&nbsp; <A href="https://blogs.sap.com/2020/05/07/configure-cloud-connector-for-rfc-connection-from-cloud-to-on-premise/" target="_blank" rel="noopener noreferrer">blog post "Configure Cloud Connector for RFC connection from cloud to on-premise".</A><BR /> <H2 id="toc-hId--686097017">3. Create Routes for Java and App Router</H2><BR /> I did this step on Ubuntu PC.<BR /> <BR /> Firstly create routes for Java application and App Router by <A href="http://cli.cloudfoundry.org/en-US/cf/create-route.html" target="_blank" rel="nofollow noopener noreferrer">cf cli create-route command</A>.<BR /> <BR /> Please replace from &lt;space name&gt; to your space name.&nbsp; Name &lt;host name of XXX&gt; as you like.<BR /> <PRE class="language-javascript"><CODE>cf create-route &lt;space name&gt; cfapps.eu10.hana.ondemand.com --hostname &lt;host name of App Router&gt;<BR /> cf create-route &lt;space name&gt; cfapps.eu10.hana.ondemand.com --hostname &lt;host name of Java App&gt;</CODE></PRE><BR /> <H2 id="toc-hId--882610522">4. Create Java Application</H2><BR /> I did this step on Windows PC.<BR /> <BR /> With maven, create a Java Application project.<BR /> <PRE class="language-javascript"><CODE>mvn archetype:generate "-DarchetypeGroupId=com.sap.cloud.sdk.archetypes" "-DarchetypeArtifactId=scp-cf-tomee" "-DarchetypeVersion=RELEASE"</CODE></PRE><BR /> I set following information during prompt.<BR /> <UL><BR /> <LI>groupId: com.sap.cloud.sdk</LI><BR /> <LI>artifactId: test-rfc</LI><BR /> <LI>version: 1.0-SNAPSHOT</LI><BR /> <LI>package: com.sap.cloud.sdk</LI><BR /> </UL><BR /> Change "manifest.yml" file.<BR /> <UL><BR /> <LI>Add the created route in step 3 to "routers" -&gt; "route"</LI><BR /> <LI>Change values of "random-route"</LI><BR /> <LI>Add the created destination to "services"</LI><BR /> </UL><BR /> <PRE class="language-javascript"><CODE>---<BR /> applications:<BR /> <BR /> - name: test-rfc<BR /> memory: 1024M<BR /> timeout: 300<BR /> routers:<BR /> - route: <A href="https://&lt;route" target="test_blank" rel="nofollow noopener noreferrer">https://&lt;route</A> host name&gt;.&lt;route domain name&gt;<BR /> random-route: false<BR /> path: application/target/test-rfc-application.war<BR /> buildpacks:<BR /> - sap_java_buildpack<BR /> env:<BR /> TARGET_RUNTIME: tomee7<BR /> SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'<BR /> JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:128m..'<BR /> services:<BR /> # - my-application-logs<BR /> - &lt;destination name&gt;<BR /> # - my-connectivity</CODE></PRE><BR /> &nbsp;<BR /> <BR /> Thought it is unusual, "Plugins Usage Analytics Maven Plugin" version 3.19.1 doesn't exist on the maven repository.&nbsp; So I changed the version on "&lt;project root&gt;/application/pom.xml".&nbsp; In addition, I changed skipUsageAnalytics value.<BR /> <PRE class="language-markup"><CODE> &lt;plugin&gt;<BR /> &lt;groupId&gt;com.sap.cloud.sdk.plugins&lt;/groupId&gt;<BR /> &lt;artifactId&gt;usage-analytics-maven-plugin&lt;/artifactId&gt;<BR /> &lt;!-- changed from 3.19.1 to 3.18.0 --&gt;<BR /> &lt;version&gt;3.18.0&lt;/version&gt;<BR /> &lt;executions&gt;<BR /> &lt;execution&gt;<BR /> &lt;goals&gt;<BR /> &lt;goal&gt;usage-analytics&lt;/goal&gt;<BR /> &lt;/goals&gt;<BR /> &lt;configuration&gt;<BR /> &lt;!-- changed from false to true --&gt;<BR /> &lt;skipUsageAnalytics&gt;true&lt;/skipUsageAnalytics&gt;<BR /> &lt;generateSalt&gt;true&lt;/generateSalt&gt;<BR /> &lt;!--<BR /> Note: A random salt is auto-generated once the project is built for the first time.<BR /> Please keep the generated salt in the POM file, for example, when pushing to git.<BR /> <BR /> To learn more, visit: <A href="https://blogs.sap.com/2018/10/23/usage-analytics-s4sdk/" target="test_blank" rel="noopener noreferrer">https://blogs.sap.com/2018/10/23/usage-analytics-s4sdk/</A><BR /> --&gt;<BR /> &lt;salt&gt;55578c0d7b7bff985020ad9ce2e033dbb9bd6425acb24eb8d4b40dcc1ba0f9b0&lt;/salt&gt;<BR /> &lt;/configuration&gt;<BR /> &lt;/execution&gt;<BR /> &lt;/executions&gt;<BR /> &lt;/plugin&gt;<BR /> </CODE></PRE><BR /> After project generation, build and deploy the Java application.<BR /> <PRE class="language-javascript"><CODE>mvn clean package &amp;&amp; cf push</CODE></PRE><BR /> Check if the deployment is successful using Curl.&nbsp; Only this command run on Ubuntu PC.<BR /> <PRE class="language-javascript"><CODE>$ curl <A href="https://test-rfc.cfapps.eu10.hana.ondemand.com/hello" target="test_blank" rel="nofollow noopener noreferrer">https://test-rfc.cfapps.eu10.hana.ondemand.com/hello</A><BR /> Hello World!</CODE></PRE><BR /> <H2 id="toc-hId--1079124027">5. Create XSUAA service and App Router</H2><BR /> I did this step on Ubuntu PC.<BR /> <H3 id="toc-hId--1569040539">5.1. Create App Router Project</H3><BR /> I created App Router using SAP Cloud SDK for Javascript cli. During prompt, input Java application name "test-rfc".<BR /> <BR /> It is not mandatory to use the cli.&nbsp; App Router and relevant codes are very simple.<BR /> <PRE class="language-javascript"><CODE>$ sap-cloud-sdk add-approuter<BR /> No 'manifest.yml' found.<BR /> Enter project name as maintained in Cloud Foundry: test-rfc<BR /> ✔ Creating files<BR /> <span class="lia-unicode-emoji" title=":white_heavy_check_mark:">✅</span> Successfully added approuter to your project.<BR /> <BR /> Generated files might need customization. Documentation available here:<BR /> - xs-security.json (for help check <A href="https://help.sap.com/viewer/4505d0bdaf4948449b7f7379d24d0f0d/2.0.02/en-US/e6fc90df44464a29952e1c2c36dd9861.html)" target="test_blank" rel="noopener noreferrer">https://help.sap.com/viewer/4505d0bdaf4948449b7f7379d24d0f0d/2.0.02/en-US/e6fc90df44464a29952e1c2c36dd9861.html)</A><BR /> - xs-app.json (for help check <A href="https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/c103fb414988447ead2023f768096dcc.html)" target="test_blank" rel="noopener noreferrer">https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/c103fb414988447ead2023f768096dcc.html)</A><BR /> - mainfest.yml (for help check <A href="https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/ba527058dc4d423a9e0a69ecc67f4593.html)" target="test_blank" rel="noopener noreferrer">https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/ba527058dc4d423a9e0a69ecc67f4593.html)</A></CODE></PRE><BR /> <H3 id="toc-hId--1765554044">5.2. Change "xs-security.json"</H3><BR /> Change "tenant-mode" value on "aprouter/xs-security.json" file.&nbsp; I have never used "shared".&nbsp; Please refer to <A href="https://developers.sap.com/tutorials/s4sdk-secure-cloudfoundry.html#0ae205fa-df73-4ab6-9c45-a47b40c491d3" target="_blank" rel="noopener noreferrer">tutorial </A>and <A href="https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/517895a9612241259d6941dbf9ad81cb.html" target="_blank" rel="noopener noreferrer">help document</A> for further detail.<BR /> <PRE class="language-javascript"><CODE>{<BR /> "xsappname": "test-rfc",<BR /> "tenant-mode": "dedicated"<BR /> }</CODE></PRE><BR /> <H3 id="toc-hId--1962067549">5.3. Create XSUAA service</H3><BR /> Create XSUAA service using xs-security.json by <A href="http://cli.cloudfoundry.org/en-US/cf/create-service.html" target="_blank" rel="nofollow noopener noreferrer">cf cli command</A>.<BR /> <PRE class="language-javascript"><CODE>cf create-service xsuaa application &lt;xsuaa name&gt; -c xs-security.json</CODE></PRE><BR /> &nbsp;<BR /> <BR /> bind XSUAA service and the Java application.<BR /> <PRE class="language-abap"><CODE>cf bind-service test-rfc &lt;xsuaa name&gt;</CODE></PRE><BR /> <H3 id="toc-hId-2136386242">5.4. Create App Router</H3><BR /> Change manifest.yml file.<BR /> <PRE class="language-javascript"><CODE>applications:<BR /> - name: test-rfc-approuter<BR /> routes:<BR /> - route: &gt;-<BR /> <A href="https://&lt;App" target="test_blank" rel="nofollow noopener noreferrer">https://&lt;App</A> Router Route host name&gt;&lt;App Router Route domain&gt;<BR /> path: .<BR /> memory: 128M<BR /> buildpacks:<BR /> - nodejs_buildpack<BR /> env:<BR /> # TENANT_HOST_PATTERN: &gt;-<BR /> # "test-rfc-(.*).cfapps.sap.hana.ondemand.com"<BR /> destinations: &gt;-<BR /> [{"name":"test-rfc","url":"https://&lt;Java Route host name&gt;.&lt;Java Route domain&gt;","forwardAuthToken":true}]<BR /> services:<BR /> - &lt;xsuaa name&gt;<BR /> </CODE></PRE><BR /> Deploy the App Router.<BR /> <PRE class="language-javascript"><CODE>cf push</CODE></PRE><BR /> Now go to App router route url via browser and redirect to XSUAA service.&nbsp; After authentication, "Hello World!" is displayed on browser.<BR /> <H2 id="toc-hId--2061691552">7. Create Connectivity</H2><BR /> I did this step on Ubuntu PC.<BR /> <BR /> Create Connectivity service.&nbsp; The Connectivity service is necessary to connect from cloud to on-premise environment according to <A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/daca64dacc6148fcb5c70ed86082ef91.html" target="_blank" rel="noopener noreferrer">Help document</A>.<BR /> <PRE class="language-javascript"><CODE>cf create-service connectivity lite &lt;connectivity name&gt;</CODE></PRE><BR /> <H2 id="toc-hId-2036762239">8. Update Java Application</H2><BR /> I did this step on Windows PC.<BR /> <BR /> Change "&lt;project root&gt;/manifest.yml" to bind created services.&nbsp; Make sure that "env" is also updated.<BR /> <PRE class="language-javascript"><CODE>---<BR /> applications:<BR /> <BR /> - name: test-rfc<BR /> memory: 1024M<BR /> timeout: 300<BR /> random-route: false<BR /> routers:<BR /> - route: <A href="https://test-rfc-java.cfapps.eu10.hana.ondemand.com" target="test_blank" rel="nofollow noopener noreferrer">https://test-rfc-java.cfapps.eu10.hana.ondemand.com</A><BR /> path: application/target/test-rfc-application.war<BR /> buildpacks:<BR /> - sap_java_buildpack<BR /> env:<BR /> TARGET_RUNTIME: tomee7<BR /> SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'<BR /> JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:128m..'<BR /> xsuaa_connectivity_instance_name: "&lt;xsuaa name&gt;"<BR /> services:<BR /> - &lt;destination name&gt;<BR /> - &lt;xsuaa name&gt;<BR /> - &lt;connectivity name&gt;</CODE></PRE><BR /> Create "&lt;project root&gt;/application/src/main/java/com/sap/cloud/sdk/RfcServlet.java".&nbsp; Please replace from &lt;destination name&gt; to your destination name.&nbsp; The servlet receive "name" url parameter, which is function module name.&nbsp; If there is no "name" parameter, "RFC PING" is called.<BR /> <BR /> I haven't implemented security in this Java App, so the app can be called without App Router though it fails.&nbsp; I posted about the security implementation in <A href="https://blogs.sap.com/2020/05/01/app-router-xsuaa%E3%81%A8java-application%E9%96%8B%E7%99%BA/" target="_blank" rel="noopener noreferrer">another article</A>, though it is in Japanese.<BR /> <PRE class="language-java"><CODE>package com.sap.cloud.sdk;<BR /> <BR /> <BR /> import com.google.gson.Gson;<BR /> import com.sap.cloud.sdk.cloudplatform.connectivity.Destination;<BR /> import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.exception.RequestExecutionException;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.rfc.RfmRequest;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.rfc.RfmRequestResult;<BR /> import org.slf4j.Logger;<BR /> import org.slf4j.LoggerFactory;<BR /> <BR /> import javax.servlet.annotation.WebServlet;<BR /> import javax.servlet.http.HttpServlet;<BR /> import javax.servlet.http.HttpServletRequest;<BR /> import javax.servlet.http.HttpServletResponse;<BR /> import java.io.IOException;<BR /> <BR /> @WebServlet("/rfc")<BR /> public class RfcServlet extends HttpServlet {<BR /> private static final long serialVersionUID = 1L;<BR /> private static final Logger logger = LoggerFactory.getLogger(RfcServlet.class);<BR /> private static final Destination destinationRfc =<BR /> DestinationAccessor.getDestination("&lt;destination name&gt;");<BR /> <BR /> @Override<BR /> protected void doGet(final HttpServletRequest request, final HttpServletResponse response)<BR /> throws IOException {<BR /> <BR /> logger.info("Start get method: " + request.getRequestURI());<BR /> String parameter = request.getParameter("name");<BR /> logger.info("Get parameter 'name': " + parameter);<BR /> if (parameter == null) {<BR /> parameter = "RFCPING";<BR /> }<BR /> Iterable names = destinationRfc.getPropertyNames();<BR /> logger.info(new Gson().toJson(names));<BR /> <BR /> try {<BR /> final RfmRequestResult rfmTest = new RfmRequest(parameter, false) //false is for non-commit<BR /> .execute(destinationRfc);<BR /> response.setContentType("application/json");<BR /> response.setCharacterEncoding("UTF-8");<BR /> response.getWriter().write(new Gson().toJson(rfmTest));<BR /> } catch (RequestExecutionException e) {<BR /> e.printStackTrace();<BR /> }<BR /> }<BR /> }</CODE></PRE><BR /> Finally, build and deploy the Java application.<BR /> <PRE class="language-javascript"><CODE># from application directory<BR /> mvn clean package &amp;&amp; cd .. &amp;&amp; cf push</CODE></PRE><BR /> &nbsp;<BR /> <H1 id="toc-hId-2133651741">Result</H1><BR /> When I open the Java Application via App router, then result is like this.<BR /> <BR /> <A href="https://&lt;App" target="test_blank" rel="nofollow noopener noreferrer">https://&lt;App</A> Router route host name&gt;.&lt;App Router route domain&gt;/rfc?name=RFC_TEST_EXTERNAL<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/30.result01-1.jpg" /></P><BR /> There are many words "Error" on the screen. but actually it is not errors.&nbsp; It just displays error mapping information.<BR /> <BR /> If you access the app without App router, Internal Server Error occurs. 2020-05-08T07:21:21+02:00 https://community.sap.com/t5/technology-blogs-by-sap/sap-cloud-sdk%E3%81%AErfmrequest%E3%81%A7rfc%E3%82%92%E8%A9%A6%E3%81%99-bapi%E3%82%82/ba-p/13445153 SAP Cloud SDKのRfmRequestでRFCを試す(BAPIも) 2020-05-11T11:07:53+02:00 Fukuhara https://community.sap.com/t5/user/viewprofilepage/user-id/44116 SAP Cloud SDK for Javaで<A href="https://help.sap.com/doc/b579bf8578954412aea2b458e8452201/1.0/en-US/com/sap/cloud/sdk/s4hana/connectivity/rfc/RfmRequest.html" target="_blank" rel="noopener noreferrer">RfmRequest</A>を使ってRFCを試してみました。メモ程度の簡単な内容ですが投稿します。<BR /> <BR /> 基本的なRFCのやり方は別記事<A href="https://blogs.sap.com/2020/05/08/how-to-call-function-modules-using-sap-cloud-sdk-for-java/" target="_blank" rel="noopener noreferrer">「How to call function modules using SAP Cloud SDK for Java」</A>を参照ください。<BR /> <H1 id="toc-hId-803500509">環境</H1><BR /> <UL><BR /> <LI>SAP Cloud SDK for Java: 3.19.1</LI><BR /> <LI>NetWeaver ABAP 7.53 SP0</LI><BR /> <LI>Java Buildpack version: sap java build pack 1.25.0</LI><BR /> </UL><BR /> <H1 id="toc-hId-606987004">開発内容</H1><BR /> <H2 id="toc-hId-539556218">ABAP側RFM</H2><BR /> いろいろなパラメータを試して見るべく、リモート呼出可能な汎用モジュールを登録。<BR /> <PRE class="language-abap"><CODE>FUNCTION y_348221_test01_rfc .<BR /> *"----------------------------------------------------------------------<BR /> *"*"ローカルインタフェース:<BR /> *" IMPORTING<BR /> *" VALUE(IV_NUM) TYPE I DEFAULT 1<BR /> *" VALUE(IS_TEST) TYPE YS348221_TEST00 OPTIONAL<BR /> *" VALUE(IT_TEST) TYPE YT348221_TEST00 OPTIONAL<BR /> *" EXPORTING<BR /> *" VALUE(EV_NUM) TYPE I<BR /> *" VALUE(ES_TEST) TYPE YS348221_TEST00<BR /> *" VALUE(ET_TEST) TYPE YT348221_TEST00<BR /> *" TABLES<BR /> *" ET_RETURN STRUCTURE BAPIRET2 OPTIONAL<BR /> *" CHANGING<BR /> *" VALUE(CV_NUM) TYPE I DEFAULT 10<BR /> *" VALUE(CS_TEST) TYPE YS348221_TEST00 OPTIONAL<BR /> *" VALUE(CT_TEST) TYPE YT348221_TEST00 OPTIONAL<BR /> *"----------------------------------------------------------------------<BR /> <BR /> ev_num = iv_num + 1.<BR /> cv_num = cv_num + 1.<BR /> <BR /> es_test = is_test.<BR /> es_test-yyint4 = es_test-yyint4 + 1.<BR /> es_test-yydate = sy-datum.<BR /> es_test-yytime = sy-uzeit.<BR /> <BR /> cs_test-yyint4 = cs_test-yyint4 + 1.<BR /> cs_test-yydate = sy-datum + 10.<BR /> cs_test-yytime = sy-uzeit + 10.<BR /> <BR /> APPEND es_test TO et_test.<BR /> APPEND cs_test TO ct_test.<BR /> <BR /> DATA lt_return TYPE bapiret2_t.<BR /> <BR /> MESSAGE e001(00) WITH 'error v1' 'error v2' 'error v3' 'error v4' INTO DATA(lv_dummy).<BR /> <BR /> CALL FUNCTION 'ISU_CRM_IL_BAPIRET2_FILL'<BR /> CHANGING<BR /> ct_msg = lt_return.<BR /> <BR /> MESSAGE i001(00) WITH 'info v1' 'info v2' 'info v3' 'info v4' INTO lv_dummy.<BR /> <BR /> CALL FUNCTION 'ISU_CRM_IL_BAPIRET2_FILL'<BR /> CHANGING<BR /> ct_msg = lt_return.<BR /> <BR /> MESSAGE s001(00) WITH 'success v1' 'success v2' 'success v3' 'success v4' INTO lv_dummy.<BR /> <BR /> CALL FUNCTION 'ISU_CRM_IL_BAPIRET2_FILL'<BR /> CHANGING<BR /> ct_msg = lt_return.<BR /> <BR /> et_return[] = lt_return.<BR /> <BR /> ENDFUNCTION.</CODE></PRE><BR /> 参照する型YS348221_TEST00は構造で、いろいろなデータ型を含めたのですが、3つくらいしか試していません。時間がなかったからです。<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/types.jpg" /></P><BR /> 型YT348221_TEST00は構造YT348221_TEST00のテーブルデータ型です。<BR /> <BR /> &nbsp;<BR /> <H2 id="toc-hId-343042713">Java開発</H2><BR /> Java側のサーブレットはこんなコード。<BR /> <PRE class="language-java"><CODE>package com.sap.cloud.sdk;<BR /> <BR /> import com.google.gson.Gson;<BR /> import com.sap.cloud.sdk.cloudplatform.connectivity.Destination;<BR /> import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.exception.RequestExecutionException;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.rfc.Fields;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.rfc.Table;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.rfc.RfmRequest;<BR /> import com.sap.cloud.sdk.s4hana.connectivity.rfc.RfmRequestResult;<BR /> import org.slf4j.Logger;<BR /> import org.slf4j.LoggerFactory;<BR /> <BR /> import javax.servlet.annotation.WebServlet;<BR /> import javax.servlet.http.HttpServlet;<BR /> import javax.servlet.http.HttpServletRequest;<BR /> import javax.servlet.http.HttpServletResponse;<BR /> import java.io.IOException;<BR /> <BR /> @WebServlet("/rfc")<BR /> public class RfcServlet extends HttpServlet {<BR /> private static final long serialVersionUID = 1L;<BR /> private static final Logger logger = LoggerFactory.getLogger(RfcServlet.class);<BR /> private static final Destination destinationRfc =<BR /> DestinationAccessor.getDestination("Erp1809Rfc");<BR /> <BR /> @Override<BR /> protected void doGet(final HttpServletRequest request, final HttpServletResponse response)<BR /> throws IOException {<BR /> <BR /> logger.info("Start get method: " + request.getRequestURI());<BR /> Fields inStructure = new Fields();<BR /> inStructure.field("YYINT4", "I", 12);<BR /> Fields exStructure = new Fields();<BR /> Fields chStructure = new Fields();<BR /> chStructure.field("YYINT4", "I", 4);<BR /> <BR /> try {<BR /> RfmRequest rfmRequest = new RfmRequest("Y_348221_TEST01_RFC", false)<BR /> .withExporting("IV_NUM", "I", 10)<BR /> .withExportingFields("IS_TEST", "YS348221_TEST00", inStructure)<BR /> .withImporting("EV_NUM", "I", 0)<BR /> .withImportingFields("ES_TEST", "YS348221_TEST00", exStructure)<BR /> .withImportingTable("ET_TEST", "YT348221_TEST00").end()<BR /> .withChanging("CV_NUM", "I", 0)<BR /> .withChangingFields("CS_TEST", "YS348221_TEST00", chStructure)<BR /> .withTableAsReturn("ET_RETURN", "BAPIRET2")<BR /> .ignoringErrors(); //ignoringErrorsをしておかないとエラーでExceptionに行く<BR /> <BR /> Table&lt;RfmRequest&gt; exTable = rfmRequest.withExportingTable("IT_TEST", "YS348221_TEST00");<BR /> exTable.row().field("YYINT4", "I", 9)<BR /> .field("YYCHAR10", "C", "ABC");<BR /> Table&lt;RfmRequest&gt; chTable = rfmRequest.withChangingTable("CT_TEST", "YS348221_TEST00");<BR /> chTable.row().field("YYINT4", "I", 14)<BR /> .field("YYCHAR10", "C", "ABCDE");<BR /> <BR /> final RfmRequestResult rfmTest = rfmRequest.execute(destinationRfc);<BR /> <BR /> response.setContentType("application/json");<BR /> response.setCharacterEncoding("UTF-8");<BR /> response.getWriter().write("IV_NUM: " + String.valueOf(rfmTest.get("IV_NUM")) + "\n");<BR /> response.getWriter().write("EV_NUM: " + String.valueOf(rfmTest.get("EV_NUM")) + "\n");<BR /> response.getWriter().write("CV_NUM: " + String.valueOf(rfmTest.get("CV_NUM")) + "\n");<BR /> response.getWriter().write("IS_TEST: " + rfmTest.get("IS_TEST").toString() + "\n");<BR /> response.getWriter().write("ES_TEST: " + rfmTest.get("ES_TEST").toString() + "\n");<BR /> response.getWriter().write("CS_TEST: " + rfmTest.get("CS_TEST").toString() + "\n");<BR /> response.getWriter().write("IS_TEST-YYINT4: " + String.valueOf(rfmTest.get("IS_TEST").getAsObject().get("YYINT4")) + "\n");<BR /> response.getWriter().write("ES_TEST-YYINT4: " + String.valueOf(rfmTest.get("ES_TEST").getAsObject().get("YYINT4")) + "\n");<BR /> response.getWriter().write("CS_TEST-YYINT4: " + String.valueOf(rfmTest.get("CS_TEST").getAsObject().get("YYINT4")) + "\n");<BR /> response.getWriter().write("IT_TEST: " + rfmTest.get("IT_TEST").getAsCollection().toString() + "\n");<BR /> response.getWriter().write("ET_TEST: " + rfmTest.get("ET_TEST").getAsCollection().toString() + "\n");<BR /> response.getWriter().write("CT_TEST: " + rfmTest.get("CT_TEST").getAsCollection().toString() + "\n");<BR /> response.getWriter().write("Error Message: " + rfmTest.getErrorMessages().toString() + "\n");<BR /> response.getWriter().write("Information Message: " + rfmTest.getInformationMessages().toString() + "\n");<BR /> response.getWriter().write("Success Message: " + rfmTest.getSuccessMessages().toString() + "\n");<BR /> <BR /> } catch (RequestExecutionException e) {<BR /> response.setContentType("application/json");<BR /> response.setCharacterEncoding("UTF-8");<BR /> response.getWriter().write(new Gson().toJson(e));<BR /> e.printStackTrace();<BR /> }<BR /> }<BR /> }</CODE></PRE><BR /> <H1 id="toc-hId-17446489">実行結果</H1><BR /> 呼び出したときのブラウザに表示される結果はこんな感じです。<BR /> <PRE class="language-markup"><CODE>IV_NUM: GsonResultPrimitive(jsonPrimitive=10)<BR /> EV_NUM: GsonResultPrimitive(jsonPrimitive=11)<BR /> CV_NUM: GsonResultPrimitive(jsonPrimitive=1)<BR /> IS_TEST: GsonResultObject(jsonObject={"YYINT4":12,"YYCHAR10":"","YYQUAN":0.00,"YYUNIT":"","YYCURR":0.00,"YYCUKY":"","YYDATE":null,"YYTIME":"19700101 000000"}, resultElementFactory=GsonResultElementFactory(gsonBuilder=com.google.gson.GsonBuilder@2d7d1b5a))<BR /> ES_TEST: GsonResultObject(jsonObject={"YYINT4":13,"YYCHAR10":"","YYQUAN":0.00,"YYUNIT":"","YYCURR":0.00,"YYCUKY":"","YYDATE":"20200511 000000","YYTIME":"19700101 085007"}, resultElementFactory=GsonResultElementFactory(gsonBuilder=com.google.gson.GsonBuilder@2d7d1b5a))<BR /> CS_TEST: GsonResultObject(jsonObject={"YYINT4":5,"YYCHAR10":"","YYQUAN":0.00,"YYUNIT":"","YYCURR":0.00,"YYCUKY":"","YYDATE":"20200521 000000","YYTIME":"19700101 085017"}, resultElementFactory=GsonResultElementFactory(gsonBuilder=com.google.gson.GsonBuilder@2d7d1b5a))<BR /> IS_TEST-YYINT4: GsonResultPrimitive(jsonPrimitive=12)<BR /> ES_TEST-YYINT4: GsonResultPrimitive(jsonPrimitive=13)<BR /> CS_TEST-YYINT4: GsonResultPrimitive(jsonPrimitive=5)<BR /> IT_TEST: DefaultResultCollection(resultElements=[GsonResultObject(jsonObject={"YYINT4":9,"YYCHAR10":"ABC","YYQUAN":0.00,"YYUNIT":"","YYCURR":0.00,"YYCUKY":"","YYDATE":null,"YYTIME":"19700101 000000"}, resultElementFactory=GsonResultElementFactory(gsonBuilder=com.google.gson.GsonBuilder@2d7d1b5a))])<BR /> ET_TEST: DefaultResultCollection(resultElements=[GsonResultObject(jsonObject={"YYINT4":13,"YYCHAR10":"","YYQUAN":0.00,"YYUNIT":"","YYCURR":0.00,"YYCUKY":"","YYDATE":"20200511 000000","YYTIME":"19700101 085007"}, resultElementFactory=GsonResultElementFactory(gsonBuilder=com.google.gson.GsonBuilder@2d7d1b5a))])<BR /> CT_TEST: DefaultResultCollection(resultElements=[GsonResultObject(jsonObject={"YYINT4":14,"YYCHAR10":"ABCDE","YYQUAN":0.00,"YYUNIT":"","YYCURR":0.00,"YYCUKY":"","YYDATE":null,"YYTIME":"19700101 000000"}, resultElementFactory=GsonResultElementFactory(gsonBuilder=com.google.gson.GsonBuilder@2d7d1b5a)), GsonResultObject(jsonObject={"YYINT4":5,"YYCHAR10":"","YYQUAN":0.00,"YYUNIT":"","YYCURR":0.00,"YYCUKY":"","YYDATE":"20200521 000000","YYTIME":"19700101 085017"}, resultElementFactory=GsonResultElementFactory(gsonBuilder=com.google.gson.GsonBuilder@2d7d1b5a))])<BR /> Error Message: [RemoteFunctionMessage(messageType=E, messageClass=00, messageNumber=001, messageText=error v1error v2error v3error v4)]<BR /> Information Message: [RemoteFunctionMessage(messageType=I, messageClass=00, messageNumber=001, messageText=info v1info v2info v3info v4)]<BR /> Success Message: [RemoteFunctionMessage(messageType=S, messageClass=00, messageNumber=001, messageText=success v1success v2success v3success v4)]</CODE></PRE><BR /> &nbsp;<BR /> <BR /> ちなみに、こんな書き方で値だけを取り出すことができます。<BR /> <PRE class="language-java"><CODE>response.getWriter().write(rfmTest.get("RFCSI_EXPORT").getAsObject().get("RFCKERNRL").asString());</CODE></PRE><BR /> また、私がよくやる書き方のこいつをやるとエラーがよく起きます。原因をわすれてしまったのですが、構造/テーブル型のパラメータがある場合にエラーとなっている記憶があります。<BR /> <PRE class="language-java"><CODE>response.getWriter().write(new Gson().toJson(rfmTest));</CODE></PRE><BR /> <H2 id="toc-hId--49984297">BAPIの場合(2020/7/16追加)</H2><BR /> RFMではなく、BAPIの場合は、使うクラスこそ変わるものの使い方は大差ないです。<BR /> <BR /> 以下は、順にユーザロック解除、ユーザ変更BAPIを呼び出す場合です。<BR /> <PRE class="language-java"><CODE> final BapiRequestResult bapiResult = new BapiRequest("BAPI_USER_UNLOCK", false)<BR /> .withExporting("USERNAME", "C", userId) //userID becomes upper case in BAPI<BR /> .withTableAsReturn("RETURN", "BAPIRET2")<BR /> .execute(destinationRfc);<BR /> <BR /> logger.debug("-----------BAPI Result---------");<BR /> logger.info(bapiResult.toString());<BR /> logger.debug(bapiResult.getSuccessMessages().get(0).getMessageText());</CODE></PRE><BR /> <PRE class="language-java"><CODE> final BapiRequestResult bapiResult = new BapiRequest("BAPI_USER_CHANGE", false) //commit triggered inside bapi<BR /> .withExporting("USERNAME", "C", userId) //userID becomes upper case in BAPI<BR /> .withExportingFields("PASSWORD", "BAPIPWD", password)<BR /> .withExportingFields("PASSWORDX", "BAPIPWDX", passwordChange)<BR /> //.withExporting("GENERATE_PWD", "C", "X") //<BR /> .withTableAsReturn("RETURN", "BAPIRET2")<BR /> .execute(destinationRfc);</CODE></PRE> 2020-05-11T11:07:53+02:00 https://community.sap.com/t5/technology-blogs-by-members/connect-to-sap-netweaver-in-a-jupyter-notebook-using-i-ohja/ba-p/13441148 Connect to SAP Netweaver in a Jupyter notebook using i-OhJa 2020-05-31T22:38:21+02:00 ronald_schertle https://community.sap.com/t5/user/viewprofilepage/user-id/595539 <H1 id="toc-hId-803381319">Introduction</H1><BR /> In this blog post I want to show how to use our solution called i-OhJa for connecting to SAP Netweaver based systems in Jupyter notebooks.<BR /> i-OhJa is a solution based on the SAP <STRONG>J</STRONG>ava <STRONG>Co</STRONG>nnector for being able to interact with SAP Netweaver systems in the application layer. It is written in the Scala programming language and provides wrapper classes for all the basic JCo classes. In addition to that it contains SAP modules specific libraries, servers, conversion and SerDe libraries for different formats and a lot more.<BR /> In the following I will show how to use Jupyter notebooks together with i-OhJa to directly interact with an SAP Netweaver system by using the i-OhJa client library and by setting up a simple server instance for getting data in a more stream-oriented way.<BR /> Jupyter notebook is a common tool for data scientists to create and share documents, code and reports. We will use the Almond kernel here to execute Scala code directly in Jupyter notebook.<BR /> <H1 id="toc-hId-606867814">Prerequisites</H1><BR /> Local installation and usage of python and Jupyter notebook is straight forward and well described on the web. In addition to that you need to install the Almond kernel and download the SAP Java Connector native library (.dll/.so) and Java archive (.jar) from SAP marketplace.<BR /> <H1 id="toc-hId-410354309">Client connection</H1><BR /> i-OhJa includes a SAP BW client library and we will use it to download time tracking data from a BW <STRONG>D</STRONG>ata<STRONG>S</STRONG>tore<STRONG>O</STRONG>bject. At the end we will aggregate the times per person and display it in a nice and simple bar chart. This will be achieved by implementing the following steps in a Scala notebook:<BR /> <OL><BR /> <LI>Load all necessary libraries</LI><BR /> <LI>Setting up the client connection to a SAP system</LI><BR /> <LI>Query for time tracking data stored in a standard DSO</LI><BR /> <LI>Aggregate the data and display it in a Vegas bar chart</LI><BR /> </OL><BR /> <H1 id="toc-hId-213840804">Data streams</H1><BR /> Getting data as a continuous stream from a SAP system requires to set up a server instance in the notebook itself. In the example shown here we will start a simple server instance that will listen on incoming RFCs issued by a SAP system. The RFC function we will use has a simple signature that allows to send a text together with a timestamp. This function module will be used in a simple ABAP report to send a ‘Hello World’ together with the current timestamp in a loop of 20 iterations to the running i-OhJa server instance in Jupyter.<BR /> <BR /> Figure: ZHELLOWORLD RFC function module<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/ZHelloworld_fuba.png" /></P><BR /> <BR /> <PRE><CODE>*&amp;---------------------------------------------------------------------*<BR /> *&amp;&nbsp;Report&nbsp;&nbsp;ZHELLOWORLD<BR /> *&amp;<BR /> *&amp;---------------------------------------------------------------------*<BR /> *&amp;<BR /> *&amp;<BR /> *&amp;---------------------------------------------------------------------*<BR /> REPORT&nbsp;zhelloworld.<BR /> <BR /> DATA:&nbsp;lv_timestamp&nbsp;TYPE&nbsp;timestampl.<BR /> <BR /> DO&nbsp;20&nbsp;TIMES.<BR /> <BR /> &nbsp;&nbsp;GET&nbsp;TIME&nbsp;STAMP&nbsp;FIELD&nbsp;lv_timestamp.<BR /> <BR /> &nbsp;&nbsp;CALL&nbsp;FUNCTION&nbsp;'ZHELLOWORLD'&nbsp;DESTINATION&nbsp;'JCO_TEST'<BR /> &nbsp;&nbsp;&nbsp;&nbsp;EXPORTING<BR /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iv_text&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;'Hello&nbsp;World'<BR /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iv_timestamp&nbsp;=&nbsp;lv_timestamp.<BR /> <BR /> &nbsp;&nbsp;WAIT&nbsp;UP&nbsp;TO&nbsp;10&nbsp;SECONDS.<BR /> <BR /> ENDDO.</CODE></PRE><BR /> <H1 id="toc-hId-17327299">Notebook implementation</H1><BR /> The following notebook includes the implementation for both scenarios described above.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/05/Jupyter_ohja-1.png" /></P><BR /> Almond runs on Ammonite REPL that allows to load managed and unmanaged java archives during runtime. We used it to load the dependencies mentioned in the prerequisites.<BR /> <BR /> Setting up a connection to a SAP system requires to provide some property values like hostname, username and password. This can be done by setting up a secured network connection and single sign on, by implementing a custom destination provider service or by simply passing the properties in the notebook itself.<BR /> <BR /> As you can see in paragraph “Get DSO data” it just takes some seconds to set up the connection to the SAP system and to download a set of nearly 250.000 records. In this simple example we chose to select only two columns: personnel number and duration.<BR /> <BR /> In the last paragraph of the notebook we run a server listening on "Hello World" requests and printing out the request instances in a human readable html format. Almond allows to update the output of a cell and we used this to display only the current requests of the stream. The output will be updated as soon as a new request arrive, which will be the case every 10 seconds.<BR /> <H1 id="toc-hId--179186206">Summary</H1><BR /> Jupyter notebook together with i-OhJa provide a simple and yet powerful solution to interactively query and process data coming directly from a SAP Netweaver system. Data Scientists can make use of this solution to build rich reports and dashboards or prototypes on productive data in SAP. The i-OhJa server scenario furthermore enables to display and plot data flowing in as streams in real time. 2020-05-31T22:38:21+02:00 https://community.sap.com/t5/technology-blogs-by-members/a-few-code-snippets-while-developing-an-adt-plugin/ba-p/13452089 A few code snippets while developing an ADT plugin 2020-06-05T16:20:51+02:00 matt https://community.sap.com/t5/user/viewprofilepage/user-id/310 <H2 id="toc-hId-933416514">Introduction</H2><BR /> I'm busy developing a plug-in for ADT. It sends information about the currently selected class, program, function group etc. to the back-end, where some analysis is done and the results are presented.<BR /> <BR /> The plug-in itself is not something that would be useful to publish, as the back-end is something useful only to my client, but I thought some snippets of how I achieved some key tasks might be helpful to others who embark on this journey.<BR /> <BR /> These were developed on Eclipse 2020-03 using<BR /> <UL><BR /> <LI>ABAP Core Development Tools 3.10.2</LI><BR /> <LI>ABAP Connectivity and Integrations Development Tools 1.120.0</LI><BR /> <LI>Eclipse PDE 3.14.300</LI><BR /> </UL><BR /> The backend is version 7.31 sp 17.<BR /> <H2 id="toc-hId-736903009">Connecting to the backend SAP system (on-premise)</H2><BR /> I wanted to connect to the backend using the same credentials as the ABAP project. My application is launched in the same was as ATC, via "Run as..."<BR /> <BR /> For this, I use the org.eclipse.debug.ui.launchShortcuts extension in my PDE project, with a class like this:<BR /> <PRE class="language-java"><CODE>public class LaunchShortcut implements ILaunchShortcut {<BR /> <BR /> @Override<BR /> public void launch(ISelection selection, String mode) {<BR /> new myAppRunner().runFromSelection(selection);<BR /> }<BR /> <BR /> @Override<BR /> public void launch(IEditorPart editorPart, String mode) {<BR /> if (editorPart instanceof MultiPageEditorPart) {<BR /> MultiPageEditorPart editor = (MultiPageEditorPart) editorPart;<BR /> new myAppRunner().runFromEditor(editor);<BR /> }<BR /> }<BR /> <BR /> }<BR /> <BR /> </CODE></PRE><BR /> To be able to get the project credentials, I'm going to need to get some kind of project object. For the first&nbsp;<EM>launch</EM> method, I can get it from&nbsp;<EM>selection</EM>.<BR /> <PRE class="language-java"><CODE> public void runFromSelection(ISelection selection) {<BR /> IProject project = ProjectUtil.getActiveAdtCoreProject(selection, null, null,<BR /> IAdtCoreProject.ABAP_PROJECT_NATURE);<BR /> if (project == null) {<BR /> MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "No selection",<BR /> "No ABAP Project selected");<BR /> } else {<BR /> ...<BR /> ...</CODE></PRE><BR /> For the second&nbsp;<EM>launch</EM> method it turns out that the editor (if it's some kind of ABAP editor), implements <EM>com.sap.adt.project.IProjectProvider&nbsp;</EM><BR /> <PRE class="language-abap"><CODE> public void runFromEditor(MultiPageEditorPart editor) {<BR /> IProject project = null;<BR /> if (editor instanceof IProjectProvider) {<BR /> IProjectProvider projectProvider = (IProjectProvider) editor;<BR /> project = projectProvider.getProject();<BR /> }<BR /> if (project == null) {<BR /> MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "No selection",<BR /> "No ABAP Project selected");<BR /> }<BR /> ...<BR /> ...</CODE></PRE><BR /> From the project, I can get the destination, connect via JCo, and run the RFC enabled function module.<BR /> <PRE class="language-java"><CODE> private void callBapi(IProject project, ArrayList&lt;MyAppObjectStr&gt; items) {<BR /> try {<BR /> String destinationId = com.sap.adt.project.AdtCoreProjectServiceFactory.createCoreProjectService()<BR /> .getDestinationId(project);<BR /> JCoDestination destination = JCoDestinationManager.getDestination(destinationId);<BR /> <BR /> JCoFunction function = destination.getRepository().getFunction("Z_MY_APP");<BR /> ...<BR /> function.execute(destination);<BR /> ...<BR /> } catch (JCoException | PartInitException e1) {<BR /> e1.printStackTrace();<BR /> }<BR /> }</CODE></PRE><BR /> <H2 id="toc-hId-540389504">Determining what I've got</H2><BR /> This took ages. Debugging, going through the classes that make up ADT, testing, trying again and again. Until eventually, I got what I wanted without any nasty yellow (or worse red) messages coming up saying things like not an API, use discouraged - or not allowed at all.<BR /> <BR /> Again, I've got the two launch shortcuts - one with an ISelection and one with an IEditorPart<BR /> <BR /> selection was quite easy<BR /> <PRE class="language-java"><CODE>if (selection instanceof ITreeSelection) { <BR /> ITreeSelection treeSelection = (ITreeSelection) selection; <BR /> ArrayList&lt;myObjects&gt; items = new ArrayList&lt;myObjects&gt;(); <BR /> for (final Iterator&lt;?&gt; i = treeSelection.iterator(); i.hasNext();) { <BR /> Object nodeObject = i.next(); <BR /> if (nodeObject instanceof TreeNode) { <BR /> TreeNode node = (TreeNode) nodeObject; <BR /> if (node.getValue() instanceof AdtObjectReference) { <BR /> AdtObjectReference value = (AdtObjectReference) node.getValue(); <BR /> myObject item = new myObject(); <BR /> item.name = value.getName(); // Name of the class for example <BR /> item.type = value.getType().split("/")[0]; // CLAS/OC for example - I only want the bit before the / <BR /> items.add(item); <BR /> } <BR /> } <BR /> } <BR /> } </CODE></PRE><BR /> IEditorPart took me a bit longer, until i released that the concrete object that's passed to here is (I think) for every ABAP editor, an implementation of com.sap.adt.tools.core.ui.editors.IAdtFormEditor<BR /> <PRE class="language-java"><CODE>if (editor instanceof IAdtFormEditor) {<BR /> String objectName = editor.getTitle();<BR /> IAdtFormEditor formEditor = (IAdtFormEditor) editor;<BR /> String objectType = formEditor.getModel().getType();<BR /> ArrayList&lt;MyObject&gt; items = new ArrayList&lt;MyObject&gt;();<BR /> MyObject myObject = new MyObject();<BR /> myObject.name = objectName.split(" ")[1]; // Splitting "SystemID ObjectName"<BR /> myObject.type = objectType.split("/")[0]; // Splitting e.g. "CLAS/OC"<BR /> items.add(myObject);<BR /> ...<BR /> }</CODE></PRE><BR /> <H2 id="toc-hId-343875999">Things to do</H2><BR /> 1. Ensure the "Run as myapp" option only appears when it's contextually correct<BR /> <BR /> 2. I'd like to run directly from a launch configuration using the org.eclipse.debug.core.launchConfigurationTypes extension in my PDE project. This would also allow me to run from the Outline of a class, for example.<BR /> <PRE class="language-java"><CODE>public class LaunchConfigurationDelegate implements ILaunchConfigurationDelegate {<BR /> <BR /> @Override<BR /> public void launch(ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor)<BR /> throws CoreException {<BR /> monitor.beginTask("Running ...", 0);<BR /> new myAppRunner().run(config, launch);<BR /> monitor.done();<BR /> }<BR /> <BR /> }<BR /> </CODE></PRE><BR /> What I've not figured out is how to get the current object from&nbsp;<STRONG>config</STRONG> or&nbsp;<STRONG>launch.</STRONG> But I have my suspicions it'll all become clear when I get the configuration functionality installed.<BR /> <BR /> 3. Completely finish my app - but after 2, that's just a question of Eclipse development, not ADT!<BR /> <H2 id="toc-hId-147362494">Most irritating aspect</H2><BR /> Obviously, it'd be lovely if we could have a fully documented set of APIs! But it doesn't have to be a stumbling block.<BR /> <BR /> No, the most irritating aspect was when I couldn't debug my Java code any more. In the end I resolved it by eliminating Larry Eillison's Java, and replacing it with SAPMachine <A href="https://sap.github.io/SapMachine/" target="test_blank" rel="nofollow noopener noreferrer">https://sap.github.io/SapMachine/</A>. That, with a fresh install of the latest Eclipse, PDE and ADT, and everything sprang back to life.<BR /> <H2 id="toc-hId--49151011">Thanks</H2><BR /> <SPAN class="mention-scrubbed">sebastian.ratz</SPAN> and <SPAN class="mention-scrubbed">armin.beil.2</SPAN> of the ADT development team.<BR /> <BR /> <SPAN class="mention-scrubbed">christian.drumm</SPAN> for his blogs on developing plugins<BR /> <BR /> <SPAN class="mention-scrubbed">andreas.gautsch</SPAN> for the <A href="https://blogs.sap.com/2019/01/24/abap-code-insight-plugin-inline-code-information-in-eclipse/" target="_blank" rel="noopener noreferrer">Code Insight</A> plugin&nbsp; and <A href="https://blogs.sap.com/2018/08/20/abap-continuous-integration-plugin-now-with-plug-and-play/" target="_blank" rel="noopener noreferrer">ABAP Continuous Improvement</A> plugin<BR /> <BR /> <SPAN class="mention-scrubbed">28f4b37a40894f18a22abc696b8154f4</SPAN> for the <A href="https://blogs.sap.com/2017/07/23/abap-favorites-plugin-for-adt/" target="_blank" rel="noopener noreferrer">ABAP Favourites</A> plugin<BR /> <BR /> <SPAN class="mention-scrubbed">thomasalexander.ritter</SPAN> for his response to the blog <A href="https://blogs.sap.com/2014/11/16/extensibility-aint-just-a-13-letter-word/" target="_blank" rel="noopener noreferrer"><EM>Extensibility Ain’t Just A 13-Letter Word</EM></A>, by "A former member".<BR /> <BR /> &nbsp;<BR /> <BR /> &nbsp; 2020-06-05T16:20:51+02:00 https://community.sap.com/t5/technology-blogs-by-sap/data-ingestion-from-sap-hana-cubes-into-sap-analytics-cloud-instalment-1/ba-p/13459475 Data ingestion from SAP HANA cubes into SAP Analytics Cloud. Instalment 1. 2020-06-30T16:49:42+02:00 quovadis https://community.sap.com/t5/user/viewprofilepage/user-id/743 <H3 id="toc-hId-1062711579">Abstract.</H3><BR /> In this article I would like to share some insight into the data ingestion techniques from SAP HANA cubes into SAP Analytics Cloud data wranglers.<BR /> <BR /> When it comes to&nbsp; SAP HANA the focus will be on using different SAP HANA cloud services available on SAP Cloud Platform [SCP] Cloud Foundry [CF].<BR /> <BR /> In this instalment, I shall start with SAP PSA (Persistence Service) HANA service on&nbsp; <A href="https://help.sap.com/viewer/a12d484310c847d2bb7ce1f0283cdb1e/Cloud/en-US/d5089968190147ce965e1f7ec29d6f44.html" target="_blank" rel="noopener noreferrer">Azure</A> CF.<BR /> <BR /> Next will follow the HaaS CF and eventually the tally will culminate with the latest HANA Cloud service on [CF].<BR /> <BR /> When it comes to SAP Analytics Cloud the product features I will be making use of are described in the Feature Scope Description (FSD) <A href="https://help.sap.com/viewer/92a4a76cf6ae454cbf55b73df1cc2f3d/release/en-US/26b634b6a5a64b9c9c6867a46c4aeedd.html" target="_blank" rel="noopener noreferrer">document</A>.<BR /> <H3 id="toc-hId-866198074">Let's go.</H3><BR /> Every analytical tool has its sweet spot. SAP Analytics Cloud [<A href="https://help.sap.com/viewer/product/SAP_ANALYTICS_CLOUD/release/en-US" target="_blank" rel="noopener noreferrer">SAC</A>] supports natively <A href="https://help.sap.com/viewer/2d7115b0e0aa4f78bfd9c06fdc1fe4f6/release/en-US/3ac0033a49a649299f060a68013c2bb6.html" target="_blank" rel="noopener noreferrer">direct</A> connectivity to a number&nbsp; of SAP Applications as data sources. SAP HANA is one of them.<BR /> <BR /> However, it has been brought to my attention that there are use cases where the live connectivity is not <EM>desirable</EM> especially with business applications that require data be fully vetted and curated at all times and where the content providers need to impose stricter controls over the data/content being delivered to the consumers.<BR /> <BR /> The live SAP HANA connection has been an <EM>outspoken</EM> advantage that SAC has had over its competition.<BR /> <BR /> Live or direct connectivity means not only there is no data replication but it also implies a <EM>semantic</EM> knowledge of the data source.<BR /> <BR /> But, and this is maybe of a less common knowledge, with SAC one can create queries and <A href="https://help.sap.com/viewer/2d7115b0e0aa4f78bfd9c06fdc1fe4f6/release/en-US/8fd8c51abff4436dbe4d96a5eca0b914.html" target="_blank" rel="noopener noreferrer">acquire</A> data directly from SAP HANA cubes with <EM>no</EM> ETL tool required.<BR /> <BR /> (This resembles a lot the universe/query paradigm found with WebIntelligence for example.)<BR /> <H4 id="toc-hId-798767288">How is it possible ?</H4><BR /> SAC sports a long list of so-called acquired data sources. Again, SAP HANA is one of them.<BR /> <BR /> SAC is a cloud appliance sitting in its own SAP Cloud Platform [SCP] sub-account (on either Cloud Foundry or SAP Neo).<BR /> <BR /> And this is where the SAP Cloud Connector [<A href="https://help.sap.com/viewer/2d7115b0e0aa4f78bfd9c06fdc1fe4f6/release/en-US/cd88cdcbc28d448f9fcb8871e33d0c92.html" target="_blank" rel="noopener noreferrer">SCC</A>] comes into the mix as it allows to leverage the cloud to on premise connectivity through the SCP connectivity service.<BR /> <BR /> Question. But SCC provides the secure communication tunnel only. So what about the data itself? How do one gets connected to a data source?<BR /> <BR /> Answer. That's where the SAC Cloud Agent [<A href="https://help.sap.com/viewer/2d7115b0e0aa4f78bfd9c06fdc1fe4f6/release/en-US/7e521fe163414afaade71f90affd153b.html" target="_blank" rel="noopener noreferrer">C4A</A>] comes into play.<BR /> <BR /> The C4A is essentially a connectivity <EM>broker</EM> - "the connection server" - a witty piece of middleware that understands the semantics of the underlying data sources.<BR /> <BR /> C4A is provided as a ready-to-deploy <EM>servlet</EM>. It is best deployed on the on-premise side together with SCC.<BR /> <H4 id="toc-hId-602253783">Let's have closer look on how to acquire data from SAP HANA Service (PSA) available on SCP Cloud Foundry on Azure .</H4><BR /> As a quick reminder all SAP HANA services on Cloud Foundry come without application runtime (no XSA). And with the exception of the PSA-based HANA service they do <EM>not</EM> offer XSC either.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import5.png" /></P><BR /> &nbsp;<BR /> <BR /> That makes live connectivity a little bit more cumbersome because it implies the deployment of the HANA Analytical Adapter [<A href="https://tools.hana.ondemand.com/#hanatools" target="_blank" rel="nofollow noopener noreferrer">HAA</A>] which is a dedicated java application that implements the SAP Information Access (InA) REST protocol required to establish the live connectivity.<BR /> <BR /> But if the data acquisition is a <EM>viable</EM> option it may help simplify the data ingestion process and help keep the cost low (by eliminating the need of using the CF application runtime for HAA deployment)<BR /> <H4 id="toc-hId-405740278">JDBC endpoint</H4><BR /> In a nutshell, all that has to be done is to expose the <EM>jdbc</EM> SQL endpoint of the SAP HANA service.<BR /> <BR /> With PSA HANA Service the jdbc SQL endpoint is already exposed on CF. However, in order to be able to use it one would need to create and bind a CF application to the service first.<BR /> <BR /> <EM>This is beyond the scope of this article but if there is interest from the readers to cover this approach I might do it in one of the next episodes. so please do vote:).</EM><BR /> <BR /> Alternatively, one can use the <STRONG>SCC</STRONG> to connect to the <STRONG>CF sub-account</STRONG> where the HANA PSA-based service has been provisioned to and then create a <A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/3dc28b456bb64fad89084d2d10af602c.html" target="_blank" rel="noopener noreferrer"><EM>service channel</EM> </A>to the HANA instance.<BR /> <BR /> As we have already made use of SCC to enable cloud to on premise connectivity from SAC side we shall re-use the same SCC for the service channel sake.<BR /> <BR /> We can create several service channels to the same [tenant] database as depicted below.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">service channels</P><BR /> &nbsp;<BR /> <BR /> For instance, this is how it looks like with SAP HANA Studio.<BR /> <BR /> There are 3 different variants of connections definitions using two different service channels ports (30515 and 30615).<BR /> <BR /> It is worth noticing is that all 3 connections point to <EM>one same tenant database</EM> (the system database is managed by SAP and cannot be accessed via the service)<BR /> <BR /> &nbsp;<BR /> <P class="image_caption" style="text-align: center;font-style: italic;overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import4.png" height="358" width="401" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">SAP HANA Studio</P><BR /> &nbsp;<BR /> <BR /> OK. From now on one can attempt to create a SAP HANA import connection with SAC.<BR /> <BR /> We shall focus on the two following options:<BR /> <OL><BR /> <LI>connect to _SYS_BIC schema&nbsp; and get access to the cubes there [with a "classic" database user]</LI><BR /> <LI>connect to a HDI container and acquire data from the container's cubes [using the user access details from the service key of the HDI container service instance.]</LI><BR /> </OL><BR /> The first option may be very convenient; when it comes to migrating from on-premise HANA development into Cloud Foundry universe.<BR /> <BR /> The latter (and preferred) option allows to fully unleash the power of hardware deployment infrastructure with the focus on container shipment as opposed to package delivery.<BR /> <H4 id="toc-hId-209226773">[_SYS_BIC]</H4><BR /> In order to demonstrate the first approach I uploaded a well known HANA SHINE package into the database.<BR /> <BR /> This <EM>mimics</EM> a typical SAP HANA development paradigm where developers would work on packages that may contain a number of cubes each.<BR /> <BR /> <EM>(on a side note: the data would be loaded into HANA tables either via HANA SDI engine or any other ETL tool (SAP SLT, SAP Data Services, SAP DataHub etc) - this is not in scope of this article)</EM><BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import6.png" /></P><BR /> &nbsp;<BR /> <H4 id="toc-hId-12713268">Let's try to connect the dots.</H4><BR /> Next step is with SAC and all that has to be done there is to create a new SAP HANA connection. (That may require having an administration profile granted to your SAC user.)<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import7.png" /></P><BR /> <P style="overflow: hidden;margin-bottom: 0px">Once we have a working connection it is time to create a model [that will contain business information required for story telling.]</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import8.png" /></P><BR /> &nbsp;<BR /> <BR /> You may pick up any cube available for this connection and then build a query to further refine the data you are about to bring into SAC model.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import10.png" /></P><BR /> &nbsp;<BR /> <BR /> Once your query is built you will execute it.<BR /> <BR /> This will start data acquisition into a new <EM>data wrangler</EM> that will be securely kept by SAC for a period of up to 7 days:<BR /> <BR /> &nbsp;<BR /> <H4 id="toc-hId--183800237">Data wrangler</H4><BR /> Data wrangler is an important concept. It holds the acquired data.<BR /> <BR /> All the subsequent operations will be performed on the SAC tenant itself.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import11.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Data wrangler</P><BR /> <BR /> <H4 id="toc-hId--380313742">Data model and smart discovery.</H4><BR /> From now the data can be further curated and eventually a model will be created.<BR /> <BR /> The data in the model can be periodically refreshed through scheduling.<BR /> <BR /> The model can be used to build stories either manually or automatically leveraging the&nbsp; the smart discovery functionality.<BR /> <BR /> For instance you may have decided to run a smart discovery based on <EM>Netamount</EM> measure.<BR /> <BR /> SAC will then generate a story with 4 pages containing the overview, the influencers, the outliers and an interactive simulation page.<BR /> <BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/06/import12.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">SmartDiscovery</P><BR /> &nbsp;<BR /> <BR /> &nbsp;<BR /> <BR /> OK. That concludes the part 1. I hope you have enjoyed reading it. Looking forward to comments.<BR /> <BR /> best wishes<BR /> <BR /> <EM>Piotr Tesny</EM><BR /> <BR /> PS.<BR /> <BR /> In the second instalment I shall demonstrate how to import data from an HDI container (option 2 above) 2020-06-30T16:49:42+02:00 https://community.sap.com/t5/technology-blogs-by-members/sap-cloud-foundry-to-on-premise-rfc-connection-using-jco/ba-p/13467090 SAP Cloud Foundry To On-Premise RFC Connection Using JCo 2020-07-30T12:29:06+02:00 former_member313918 https://community.sap.com/t5/user/viewprofilepage/user-id/313918 <BLOCKQUOTE>The SAP Java Connector (SAP JCo) is a development library that enables development of SAP compatible components in Java. It can be used to communicate with on-premise SAP systems via SAP's RFC protocol.<BR /> <BR /> (Source: <A href="https://support.sap.com/en/product/connectors/jco.html)" target="test_blank" rel="noopener noreferrer">https://support.sap.com/en/product/connectors/jco.html)</A></BLOCKQUOTE><BR /> In this tutorial, we are going to learn how can we call a function module in an on-premise ABAP system by SAP JCo (Inbound).<BR /> <BR /> Let’s go step by step.<BR /> <UL><BR /> <LI><STRONG>Step 1</STRONG>: As a starting point, I build a maven web project with the following code:</LI><BR /> </UL><BR /> <PRE class="language-java"><CODE>package com.test.jco;<BR /> <BR /> import java.io.IOException;<BR /> import java.io.PrintWriter;<BR /> import javax.servlet.ServletException;<BR /> import javax.servlet.annotation.WebServlet;<BR /> import javax.servlet.http.HttpServlet;<BR /> import javax.servlet.http.HttpServletRequest;<BR /> import javax.servlet.http.HttpServletResponse;<BR /> <BR /> <BR /> import com.sap.conn.jco.JCoDestination;<BR /> import com.sap.conn.jco.JCoDestinationManager;<BR /> import com.sap.conn.jco.JCoFunction;<BR /> import com.sap.conn.jco.JCoParameterList;<BR /> import com.sap.conn.jco.JCoRepository;<BR /> <BR /> <BR /> @WebServlet("/ConnectRFC/*")<BR /> <BR /> public class ConnectRFC extends HttpServlet {<BR /> <BR /> private static final long serialVersionUID = 1L;<BR /> <BR /> protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {<BR /> <BR /> PrintWriter responseWriter = response.getWriter();<BR /> <BR /> try {<BR /> <BR /> // access the RFC Destination "Test"<BR /> JCoDestination destination = JCoDestinationManager.getDestination("Test");<BR /> <BR /> // make an invocation of STFC_CONNECTION in the backend<BR /> JCoRepository repo = destination.getRepository();<BR /> JCoFunction stfcConnection = repo.getFunction("STFC_CONNECTION");<BR /> <BR /> JCoParameterList imports = stfcConnection.getImportParameterList();<BR /> imports.setValue("REQUTEXT", "JCO successful");<BR /> <BR /> stfcConnection.execute(destination);<BR /> <BR /> JCoParameterList exports = stfcConnection.getExportParameterList();<BR /> String echotext = exports.getString("ECHOTEXT");<BR /> String resptext = exports.getString("RESPTEXT");<BR /> <BR /> responseWriter.println(echotext+":"+resptext);<BR /> } catch (Exception e) {<BR /> <BR /> e.printStackTrace();<BR /> <BR /> }<BR /> <BR /> }<BR /> <BR /> }</CODE></PRE><BR /> The explanation goes as follows:<BR /> <OL><BR /> <LI>"Test" is the name of the destination which will be used after a few steps.</LI><BR /> <LI>"STFC_CONNECTION" is a standard ABAP function module, which I am using here to test the connectivity.</LI><BR /> </OL><BR /> Following JCo dependency needs to be included in your project.<BR /> <PRE class="language-java"><CODE>&lt;dependencies&gt;<BR /> &lt;dependency&gt;<BR /> &lt;groupId&gt;com.sap.cloud&lt;/groupId&gt;<BR /> &lt;artifactId&gt;neo-java-web-api&lt;/artifactId&gt;<BR /> &lt;version&gt;[3.71.8,4.0.0)&lt;/version&gt;<BR /> &lt;scope&gt;provided&lt;/scope&gt;<BR /> &lt;/dependency&gt;<BR /> &lt;/dependencies&gt;</CODE></PRE><BR /> &nbsp;<BR /> <UL><BR /> <LI><STRONG>Step 2</STRONG>: Now we need to log into the SAP CF subaccount, where we want to deploy our application. Here we need to create and bind instances for the following three services:<BR /> <UL><BR /> <LI>Connectivity Service</LI><BR /> <LI>Destination Service</LI><BR /> <LI>XSUAA service</LI><BR /> </UL><BR /> </LI><BR /> </UL><BR /> I have created these service instances and named them as following - <STRONG>jco_con , jco_dest, </STRONG>and<STRONG> jco_xs</STRONG>. Select the service plan as application and Provide the following configuration in parameters while creating xsuaa instance. Here "connect-rfc" is the app name by which I will deploy my java application in CF.<BR /> <PRE class="language-java"><CODE>{<BR /> "xsappname" : "connect-rfc",<BR /> "tenant-mode": "dedicated",<BR /> "scopes": [<BR /> {<BR /> "name": "$XSAPPNAME.all",<BR /> "description": "all"<BR /> }<BR /> ]<BR /> }</CODE></PRE><BR /> &nbsp;<BR /> <UL><BR /> <LI><STRONG>Step 3</STRONG>: Now deploy the war file to the subaccount with the following manifest.yml configuration.</LI><BR /> </UL><BR /> <PRE class="language-java"><CODE>---<BR /> <BR /> applications:<BR /> <BR /> <BR /> <BR /> - name: connect-rfc<BR /> <BR /> buildpacks:<BR /> <BR /> - sap_java_buildpack<BR /> <BR /> env:<BR /> <BR /> SAP_JWT_TRUST_ACL: '[{"clientid":"*","identityzone":"*"}]'<BR /> <BR /> xsuaa_connectivity_instance_name: "jco_xs"<BR /> <BR /> services:<BR /> <BR /> - jco_xs<BR /> <BR /> - jco_con<BR /> <BR /> - jco_dest</CODE></PRE><BR /> &nbsp;<BR /> <UL><BR /> <LI><STRONG>Step 4</STRONG>: Create a node (<EM>approuter )</EM> ** . Make necessary arrangements into xs-app.json (Point the URL to the destination). Finally, Deploy this in the subaccount with the following manifest.yml configuration.<BR /> <PRE class="language-java"><CODE>---<BR /> <BR /> applications:<BR /> <BR /> <BR /> <BR /> - name: approuter-jco<BR /> <BR /> path: ./<BR /> <BR /> buildpacks:<BR /> <BR /> - nodejs_buildpack<BR /> <BR /> memory: 120M<BR /> <BR /> env:<BR /> <BR /> NODE_TLS_REJECT_UNAUTHORIZED: 0<BR /> <BR /> destinations: &gt;<BR /> <BR /> [<BR /> <BR /> {"name":"dest", "url" :"https://&lt;your java application url&gt;/ConnectRFC", "forwardAuthToken": true }<BR /> <BR /> ]<BR /> <BR /> services:<BR /> <BR /> - jco_xs​</CODE></PRE><BR /> When choosing the application route, you are requested to login. Provide the credentials known by the IdP you configured in&nbsp;<SPAN class="ph uicontrol">Roles &amp; Trust</SPAN>. After successful login, you are routed to the java application which is then executed. It prompts an error that destination "Test" does not exist, which is obvious as we didn't create a destination till now.</LI><BR /> <LI><STRONG>Step 5</STRONG>: Create an RFC destination named "Test" in your destination instance.</LI><BR /> <LI><STRONG>Step 6</STRONG>: Configure the system mapping and the function module in the&nbsp;<SPAN class="ph pname">Cloud Connector</SPAN>. Provide access to the function module "STFC_CONNECTION".</LI><BR /> </UL><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/07/1-35.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">cloud connector</P><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/07/2-20.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic;font-family: 'SAPRegular', 'Helvetica Neue', Arial, sans-serif">SAP Cloud Platform - CF</P><BR /> &nbsp;<BR /> <UL><BR /> <LI><STRONG>Step 7</STRONG>: Run approuter, provide the credentials. This time you will receive the output of your Servlet. I received the following output.</LI><BR /> </UL><BR /> <PRE class="language-abap"><CODE>JCO successful:SAP R/3 Rel. 752 Sysid: XXX Date: 20200725 Time: 110012 Logon_Data: 100/XXXX/E<BR /> </CODE></PRE><BR /> &nbsp;<BR /> <BLOCKQUOTE>Note : In this tutorial, I used approuter for authentication purpose. You can use AppToAppSSO to propagate authentication token. Token is required for On-Premise connectivity.</BLOCKQUOTE><BR /> &nbsp;<BR /> <BR /> **Follow the steps in <A class="xref" title="The application router is the single point-of-entry for an application running in the Cloud Foundry environment on SAP Cloud Platform. The application router is used to serve static content, authenticate users, rewrite URLs, and forward or proxy requests to other micro services while propagating user information." href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/01c5f9ba7d6847aaaf069d153b981b51.html" target="_blank" rel="noopener noreferrer">Application Router</A>&nbsp;or use the demo file&nbsp;<SPAN class="keyword">approuter.zip</SPAN>&nbsp;(<A class="xref" title="https://help.sap.com/http.svc/download?deliverable_id=21564649" href="https://help.sap.com/http.svc/download?deliverable_id=21564649" target="_blank" rel="noopener noreferrer">download</A>).<BR /> <BR /> With this, I would like to conclude the tutorial. For more details, follow the below links :<BR /> <OL><BR /> <LI><A href="https://support.sap.com/en/product/connectors/jco.html" target="_blank" rel="noopener noreferrer">https://support.sap.com/en/product/connectors/jco.html</A></LI><BR /> <LI><A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/e54cc8fbbb571014beb5caaf6aa31280.html" target="_blank" rel="noopener noreferrer">https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/e54cc8fbbb571014beb5caaf6aa31280.html</A></LI><BR /> <LI><A href="https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/7e306250e08340f89d6c103e28840f30.html" target="_blank" rel="noopener noreferrer">https://help.sap.com/viewer/cca91383641e40ffbe03bdc78f00f681/Cloud/en-US/7e306250e08340f89d6c103e28840f30.html</A></LI><BR /> </OL><BR /> &nbsp; 2020-07-30T12:29:06+02:00 https://community.sap.com/t5/technology-blogs-by-sap/analytics-agent-on-paraya-glassfish/ba-p/13474152 Analytics Agent on Paraya Glassfish 2020-09-15T11:06:12+02:00 former_member207606 https://community.sap.com/t5/user/viewprofilepage/user-id/207606 The SAP Analytics Agent is intended to connect on Premise Systems via the Cloud Connector to SAP Analytics cloud.<BR /> <BR /> The agent itself comes as a war file deployable for Apache Tomcat servers.<BR /> <TABLE style="border-collapse: collapse;width: 100%" border="1"><BR /> <TBODY><BR /> <TR><BR /> <TD style="width: 100%"><STRONG>DISCLAIMER</STRONG>: This is an experimental setup. It is <STRONG>NOT SUPPORTED</STRONG> and should not be used in a productive environment.</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> Despite Tomcat being the most widely used Java application server I recently came across an environment where Tomcat was not available but Glassfish was the Java Server of choice. In this blog I would like to share the results of my experiments.<BR /> <TABLE style="border-collapse: collapse;width: 100%" border="1"><BR /> <TBODY><BR /> <TR><BR /> <TD style="width: 100%"><BR /> <BR /> TL;DR<BR /> <BR /> The Analytics Agent seems to be running fine on Glassfish too. Only simple queries were used in my experiments - so this is still a very weak statement.</TD><BR /> </TR><BR /> </TBODY><BR /> </TABLE><BR /> &nbsp;<BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">For this tutorial we need:</P><BR /> <BR /> <UL style="margin-left: .375in;direction: ltr;margin-top: 0in;margin-bottom: 0in" type="disc"><BR /> <LI style="margin-top: 0;margin-bottom: 0;vertical-align: middle"><SPAN style="font-family: Calibri;font-size: 11.0pt">A SAC tennant where we have admin rights</SPAN></LI><BR /> <LI style="margin-top: 0;margin-bottom: 0;vertical-align: middle"><SPAN style="font-family: Calibri;font-size: 11.0pt">An SAP JCO Adapter Version 3 SF 20&nbsp; - search for Java Connector at <A href="https://launchpad.support.sap.com/#/softwarecenter" target="_blank" rel="noopener noreferrer">https://launchpad.support.sap.com/#/softwarecenter</A></SPAN></LI><BR /> <LI style="margin-top: 0;margin-bottom: 0;vertical-align: middle"><SPAN style="font-family: Calibri;font-size: 11.0pt">An up and running SAP Cloud Connector with access to the internet</SPAN></LI><BR /> <LI style="margin-top: 0;margin-bottom: 0;vertical-align: middle"><SPAN style="font-family: Calibri;font-size: 11.0pt">The Analytics Agent war file (search via the link above for "analytics agent") - SAP Analytics Cloud Agent 1.0.83 was used here.</SPAN></LI><BR /> <LI style="margin-top: 0;margin-bottom: 0;vertical-align: middle"><SPAN style="font-family: Calibri;font-size: 11.0pt">The Paraya Glassfish 5 Web Application Server (Community Edition) - download via their website</SPAN></LI><BR /> <LI style="margin-top: 0;margin-bottom: 0;vertical-align: middle"><SPAN style="font-family: Calibri;font-size: 11.0pt">A backend system (here we use BW/4)&nbsp;</SPAN></LI><BR /> </UL><BR /> &nbsp;<BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">First we download and install the Paraya Glassfish community edition.</P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">I will install it on my local machine on Windows 10 which is pretty much just unzipping it to a folder on my local harddrive. I have created a folder <EM>\paraya5</EM></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">Then we copy the JCO files to the Paraya <EM>\lib</EM> folder <SPAN style="font-size: 11pt"><EM>payara5\glassfish\lib</EM>&nbsp;</SPAN></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">and start the server via <EM><SPAN style="font-size: 11pt">payara5\glassfish\asadmin.bat</SPAN></EM></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">I've had a bit of an issue with my JDK not being picked up - so I made some changes to the config of glassfish <EM><SPAN style="font-size: 11pt">payara5\\glassfish\config\asenv.bat to specifically point to the intended JDK.</SPAN></EM></P><BR /> <BR /> <PRE class="language-c"><CODE>set AS_JAVA=C:\Program Files\Java\jdk-11</CODE></PRE><BR /> <P lang="en-US" style="margin: 0in 0in 0in 0.375in;font-family: Calibri;font-size: 11pt;padding-left: 80px"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">After starting the Glassfish we can reach the admin console via the URL :&nbsp;<A href="http://127.0.0.1:4848" target="_blank" rel="nofollow noopener noreferrer">http://127.0.0.1:4848</A></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">No admin password is required in the default setup.</P><BR /> <P lang="en-US">Then we deploy the Analytics Agent war file via&nbsp;<EM>Applications-&gt; Deploy </EM>or the direct link</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard01-1.jpg" /></P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard02.jpg" /></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">The Analytics Agent will start and be available via <A href="http://127.0.0.1:8080" target="_blank" rel="nofollow noopener noreferrer">http://127.0.0.1:8080</A></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">Then we need to create an Analytics Agent user to be able to access the just deployed application. We go back to the command line where we started the Paraya Server using asadmin.bat</P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">In the admin console we enter:</P><BR /> <BR /> <PRE class="language-c"><CODE>asamin&gt; create-file-user --groups Services user1</CODE></PRE><BR /> <P lang="en-US" style="margin: 0in 0in 0in 0.375in;font-family: Calibri;font-size: 11pt;text-align: left">This will create a user: <EM>user1</EM> that belongs to the group "<EM>Services</EM>" then we will be prompted to create a password we will need later</P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in 0in 0in 0.375in;font-family: Calibri;font-size: 11pt;text-align: left">We switch back to the <STRONG>SAC Tennant</STRONG>.</P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in 0in 0in 0.375in;font-family: Calibri;font-size: 11pt;text-align: left"><EM>I assume that this is the first CloudConnector connected to SAC</EM></P><BR /> <P lang="en-US" style="margin: 0in 0in 0in 0.375in;font-family: Calibri;font-size: 11pt;text-align: left">We go to <EM>System-&gt;Administration-&gt;Datasource Configuration</EM></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in 0in 0in 0.375in;font-family: Calibri;font-size: 11pt;text-align: left">We need to enable CC Connections to the tenant by activating the SAP CP Account. I have added my email address and subsequently the Subaccount number can be seen.</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard03.jpg" /></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">We copy this number and go next to our <STRONG>Cloud Connector </STRONG>administration.</P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">Here we create a new connection to our SAC Tennant. The quired information can be taken from the previous step in the SAC Tennant. Just make sure that your Subaccount user has the Cloud Connector Admin role.</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard04.jpg" /></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">Next we add the connection details to our Glassfish server. I have both the Cloud Connector and Glassfish running on the same machine: So this gives the following configuration:</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard05.jpg" /></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">Make sure to add the URL Path /C4_AGENT/ to the Resources (Path+AllSubPath - see Arrow) or you will get an "access denied" entry in you CC Log files.</P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">As the next step we go back to the <STRONG>SAC Tennant:</STRONG></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">To <EM>System-&gt;Administration-&gt;Datasource Configuration a</EM>nd add an onPremise Datasource</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard06.jpg" /></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">In the Cloud Connector we have configured the "Virtual Host" to be <EM>127.0.0.1</EM> Port <EM>8080</EM> and this is the information we put here.</P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">The user + password is for the Analytics Agent and was previously configured by us via the Glassfish Admin Console (user1 + password)</P><BR /> <P lang="en-US" style="padding-left: 40px">So we have all the required information to fill in the details for the <EM>Default Location</EM>:</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard07.jpg" height="504" width="286" /></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">To configure the connection to the BW/4 System is the last part and is surprisingly done <STRONG>via SAC</STRONG> and not within the Analytics Agent.</P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">We go to <EM>System-&gt; Connection</EM> and <SPAN style="text-decoration: underline">add a new Connection</SPAN>:</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard08.jpg" /></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;font-family: Calibri;font-size: 11.0pt">We add the system details and our BW/4 login credentials (we need the SID, System Number, Client ID, Application Server URL, User Credentials)</P><BR /> <P lang="en-US">The server URL needs to be accessible from the Analytics Agent, make sure that no Firewall is blocking the agent from accessing the BW/4 system. There is no need to open the BW/4 system to the internet.</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard09.jpg" height="484" width="323" /></P><BR /> <P lang="en-US"></P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt">Finally we can create a new Model based on the just created Data Connection:</P><BR /> <P lang="en-US" style="margin: 0in;margin-left: .375in;font-family: Calibri;font-size: 11.0pt"><EM>GetDataFromSource-&gt; BW/4</EM> and then we select the just created Connection.</P><BR /> <P lang="en-US" style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2020/09/Clipboard10-1.jpg" /></P><BR /> <P lang="en-US">From there we can use the model and create a story based on it.</P><BR /> <P lang="en-US"></P> 2020-09-15T11:06:12+02:00 https://community.sap.com/t5/technology-blogs-by-members/rfc-gateway-security-part-1-basic-understanding/ba-p/13475684 RFC Gateway security, part 1 - basic understanding 2021-01-26T09:05:26+01:00 JoeGoerlich https://community.sap.com/t5/user/viewprofilepage/user-id/2716 From my experience the RFC Gateway security is for many SAP Administrators still a not well understood topic. As a result many SAP systems lack for example of proper defined ACLs to prevent malicious use of the RFC Gateway.<BR /> <BR /> After an attack vector was published in the talk "SAP Gateway to Heaven" from Mathieu Geli and Dmitry Chastuhin at OPDCA 2019 Dubai (<A href="https://github.com/gelim/sap_ms" target="_blank" rel="nofollow noopener noreferrer">https://github.com/gelim/sap_ms</A>) the RFC Gateway security is even more important than ever. This publication got considerable public attention as <STRONG>10KBLAZE</STRONG>.<BR /> <BR /> With this blogpost series i try to give a comprehensive explanation of the RFC Gateway Security:<BR /> <BR /> Part 1: General questions about the RFC Gateway and RFC Gateway security.<BR /> <A href="https://blogs.sap.com/2021/01/27/rfc-gateway-security-part-2-reginfo-acl/" target="_blank" rel="noopener noreferrer">Part 2: reginfo ACL in detail.</A><BR /> <A href="https://blogs.sap.com/2021/01/29/rfc-gateway-security-part-3-secinfo-acl/" target="_blank" rel="noopener noreferrer">Part 3: secinfo ACL in detail.</A><BR /> <A href="https://blogs.sap.com/2021/02/01/rfc-gateway-security-part-4-prxyinfo-acl/" target="_blank" rel="noopener noreferrer">Part 4: prxyinfo ACL in detail.</A><BR /> <A href="https://blogs.sap.com/2021/02/03/rfc-gateway-security-part-5-acls-and-the-rfc-gateway-security/" target="_blank" rel="noopener noreferrer">Part 5: Security considerations related to these ACLs.</A><BR /> <A href="https://blogs.sap.com/2021/02/05/rfc-gateway-security-part-6-logging/" target="_blank" rel="noopener noreferrer">Part 6: RFC Gateway Logging.</A><BR /> <A href="https://blogs.sap.com/2021/11/10/rfc-gateway-security-part-7-secure-communication/" target="_blank" rel="noopener noreferrer">Part 7: Secure communication</A><BR /> <A href="https://blogs.sap.com/2023/02/28/rfc-gateway-security-part-8-os-command-execution-using-sapxpg/" target="_blank" rel="noopener noreferrer">Part 8: OS command execution using sapxpg</A><BR /> <A href="https://blogs.sap.com/2023/03/21/rfc-gateway-security-part-9-enhanced-security-for-sapxpg/" target="_blank" rel="noopener noreferrer">Part 9: enhanced security for sapxpg</A><BR /> <H6 id="toc-hId-1451689566">Updates:</H6><BR /> <H6 id="toc-hId-1255176061">2023-11-15: Added usage type 'extern-to-extern RFC communication with JCo&nbsp;3.x'<BR /> 2023-03-21: Added Part 9: enhanced security for sapxpg<BR /> 2023-02-28: Added Part 8: OS command execution using sapxpg<BR /> 2021-11-10: Added Part 7: Secure communication</H6><BR /> <BR /> <HR /><BR /> <BR /> <H1 id="toc-hId-413248961">Basic understanding</H1><BR /> &nbsp;<BR /> <BR /> In the following i will do the question and answer game to develop a basic understanding of the RFC Gateway, the RFC Gateway security and its related terms.<BR /> <H2 id="toc-hId-345818175">What is the RFC Gateway?</H2><BR /> <P style="padding-left: 40px">The RFC Gateway can be seen as a communication middleware. The RFC Gateway act as an RFC Server which enables RFC function modules to be used by RFC clients. It also enables communication between work or server processes of SAP NetWeaver AS and external programs.</P><BR /> <P style="padding-left: 40px">From a technical perspective the RFC Gateway is a SAP kernel process (gwrd, gwrd.exe) running on OS level as user &lt;sapsid&gt;adm.</P><BR /> <BR /> <H2 id="toc-hId-149304670">Where can we find the RFC Gateway?</H2><BR /> <P style="padding-left: 40px">There are three places where we can find an RFC Gateway:</P><BR /> <BR /> <OL><BR /> <LI style="list-style-type: none"><BR /> <UL><BR /> <LI>In SAP NetWeaver Application Server ABAP: Every Application Server has a built-in RFC Gateway.<IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2021/01/Ohne-Titel2.png" height="343" width="328" /></LI><BR /> <LI>In SAP NetWeaver Application Server Java: The SCS instance has a built-in RFC Gateway. <IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2021/01/Ohne-Titel-2.png" height="407" width="342" /></LI><BR /> <LI>The Stand-alone RFC Gateway: As a dedicated RFC Gateway serving for various RFC clients or as an additional component which may be used to extend a SAP NW AS ABAP or AS Java system.</LI><BR /> </UL><BR /> </LI><BR /> </OL><BR /> <H2 id="toc-hId--47208835">Who can access the RFC Gateway in general</H2><BR /> <P style="padding-left: 40px">The RFC Gateway is by default reachable via the services 'sapgw&lt;InstNo&gt;' and 'sapgw&lt;InstNo&gt;s' which can be mapped to the ports '33&lt;InstNo&gt;' and '48&lt;InstNo&gt;'. Access to this ports is typically restricted on network level.</P><BR /> <P style="padding-left: 40px">There may also be an ACL in place which controls access on application level. The location of this ACL can be defined by parameter 'gw/acl_file'.</P><BR /> <BR /> <H2 id="toc-hId--243722340">Which usage types are there?</H2><BR /> &nbsp;<BR /> <P style="overflow: hidden;margin-bottom: 0px;padding-left: 40px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2021/01/Bildschirmfoto-2021-01-25-um-11.24.10-3.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">This diagram shows all use-cases except `Proxy to other RFC Gateways´. The subsequent blogs of will describe each individually.</P><BR /> &nbsp;<BR /> <P style="padding-left: 40px"><STRONG>'Registered external RFC Servers'</STRONG></P><BR /> <P style="padding-left: 40px">The RFC Gateway allows 'external RFC Server programs' (also known as 'Registered Server' or 'Registered Server Program') to register to itself and allows RFC clients to consume the functions offered by these programs.</P><BR /> <P style="padding-left: 40px">An example would be 'Trex_&lt;SID&gt;_&lt;timestamp&gt;' registered at the RFC Gateway of the SAP NW AS ABAP from the server running SAP TREX and consumed by the same AS ABAP as an RFC client.</P><BR /> <P style="padding-left: 40px">Another example would be 'IGS.&lt;SID&gt;' of SAP IGS registered at the RFC Gateway of the SAP NW AS ABAP from the same server as AS ABAP (since it is also part of it) and consumed by the same AS ABAP as an RFC client.</P><BR /> <P style="padding-left: 40px"><STRONG>'Started external RFC Servers'</STRONG></P><BR /> <P style="padding-left: 40px">The RFC Gateway is capable to start programs on the OS level.</P><BR /> <P style="padding-left: 40px">Common examples are the program 'tp' for transport management via STMS started on the RFC Gateway host of AS ABAP or the program 'gnetx.exe' for the graphical screen painter started on the SAP GUI client host.</P><BR /> <P style="padding-left: 40px">While typically remote servers start the to-be-registered program on the OS level by themselves, there may be cases where starting a program is used to register a 'Registered Server Program' at the RFC Gateway. In these cases the program started by the RFC Gateway may also be the program which tries to register to the same RFC Gateway.</P><BR /> <BR /> <BLOCKQUOTE style="padding-left: 40px"><BR /> <P style="padding-left: 40px"><STRONG>Please note:</STRONG> One should be aware that starting a program using the RFC Gateway is an interactive task. This means the call of a program is always waiting for an answer before it times out. If the called program is not an RFC enabled program (compiled with the SAP RFC library) the call will time out, but the program is still left running on the OS level!<BR /> To overcome this issue the RFC enabled program 'SAPXPG' can be used as a wrapper to call any OS command. This is for example used by AS ABAP when starting external commands using transaction SM49/SM69.</P><BR /> </BLOCKQUOTE><BR /> <P style="padding-left: 40px"><STRONG>'RFC destinations'</STRONG></P><BR /> <P style="padding-left: 40px">Most common use-case is the SAP-to-SAP communication, in other words communication via RFC connections between SAP NetWeaver AS systems, but also communication from RFC clients using the SAP Java Connector (JCo) or the SAP .NET Connector (NCo) to SAP NetWeaver systems.</P><BR /> <P style="padding-left: 40px">The RFC Gateway hands over the request from the RFC client to the dispatcher which assigns it to a work process (AS ABAP) or to a server process (AS Java).</P><BR /> <P style="padding-left: 40px"><STRONG>'Proxy to other RFC Gateways'</STRONG></P><BR /> <P style="padding-left: 40px">The RFC Gateway can be used to proxy requests to other RFC Gateways.</P><BR /> <P style="padding-left: 40px"><STRONG>'extern-to-extern RFC communication with JCo&nbsp;3.x'</STRONG></P><BR /> <P style="padding-left: 40px">As of JCo 3.0.10, there is also a use-case where a JCo based RFC Client communicates via the RFC Gateway with a JCo based registered external RFC server.</P><BR /> <BR /> <BLOCKQUOTE><BR /> <P style="padding-left: 40px"><STRONG>Please note:</STRONG> For security reasons, this usage type is not recommended. For more details, see <A href="https://me.sap.com/notes/1877907" target="_blank" rel="noopener noreferrer">SAP Note 1877907</A>.</P><BR /> </BLOCKQUOTE><BR /> <H2 id="toc-hId--440235845">What about the reginfo ACL?</H2><BR /> <P style="padding-left: 40px">The reginfo file is holding rules controlling which remote servers (based on their hostname/ip-address) are allowed to either register, access or cancel which 'Registered Server Programs' (based on their program alias (also known as 'TP name')).</P><BR /> <P style="padding-left: 40px">Its location is defined by parameter 'gw/reg_info'.<BR /> In case of AS ABAP for example it may be defined as '$(DIR_GLOBAL)$(DIR_SEP)security$(DIR_SEP)data$(DIR_SEP)$(FN_REG_INFO)' to make sure all RFC Gateways of the application servers of the same system relay on the same configuration.</P><BR /> <BR /> <H2 id="toc-hId--636749350">What about the secinfo ACL?</H2><BR /> <P style="padding-left: 40px">The secinfo file is holding rules controlling which programs (based on their executable name or fullpath, if not in $PATH) can be started by which user calling from which host(s) (based on its hostname/ip-address) on which RFC Gateway server(s) (based on their hostname/ip-address).</P><BR /> <P style="padding-left: 40px">Its location is defined by parameter 'gw/sec_info'.<BR /> In case of AS ABAP for example it may be defined as '$(DIR_GLOBAL)$(DIR_SEP)security$(DIR_SEP)data$(DIR_SEP)$(FN_SEC_INFO)' to make sure all RFC Gateways of the application servers of the same system relay on the same configuration.</P><BR /> <BR /> <H2 id="toc-hId--833262855">How are reginfo and secinfo related?</H2><BR /> <P style="padding-left: 40px">As we learnt before the reginfo and secinfo are defining rules for very different use-cases, so they are not related.</P><BR /> <BR /> <H2 id="toc-hId--682522003">What about the prxyinfo ACL?</H2><BR /> <P style="padding-left: 40px">The prxyinfo file is holding rules controlling which source systems (based on their hostname/ip-address) are allowed to talk to which destination systems (based on their hostname/ip-address) over the current RFC Gateway.</P><BR /> <P style="padding-left: 40px">Its location is defined by parameter 'gw/prxy_info'.<BR /> In case of AS ABAP for example it may be defined as '$(DIR_GLOBAL)$(DIR_SEP)security$(DIR_SEP)data$(DIR_SEP)$(FN_PRXY_INFO)' to make sure all RFC Gateways of the application servers of the same system relay on the same configuration.</P><BR /> <BR /> <H2 id="toc-hId--879035508">What about the SNC System ACL?</H2><BR /> <P style="padding-left: 40px">RFCs between two SAP NetWeaver AS ABAP systems are typically controlled on network level only. The RFC Gateway does not perform any additional security checks.</P><BR /> <P style="padding-left: 40px">When using SNC to secure RFC destinations on AS ABAP the so called 'SNC System ACL', also known as 'System Authentication', is introduced and must be maintained accordingly.</P><BR /> <P style="padding-left: 40px">This ACL is applied on the ABAP layer and is maintained in transaction SNC0.</P><BR /> <BR /> <BLOCKQUOTE><BR /> <P style="padding-left: 40px"><STRONG>Please note:</STRONG> 'SNC System ACL' is not a feature of the RFC Gateway itself.</P><BR /> </BLOCKQUOTE><BR /> &nbsp;<BR /> <H2 id="toc-hId--1075549013">What about the SNC User ACL?</H2><BR /> <P style="padding-left: 40px">RFCs between RFC clients using JCo/NCo or Registered Server Programs and the AS ABAP are typically controlled on network level only. The RFC Gateway does not perform any additional security checks.</P><BR /> <P style="padding-left: 40px">When using SNC to secure logon for RFC Clients or Registered Server Programs the so called 'Extended SNC Access Control List (ACL) for Users', also known as 'User Authentication', is introduced. With this, the AS ABAP verifies whether the RFC client is allowed to logon with the combination of username and SNC name sent in the connection attempt. The SNC name taken from the X.509 client certificate is used for the authentication in favor of password based logon.</P><BR /> <P style="padding-left: 40px">This Extended SNC ACL for Users is applied on the ABAP layer and is maintained in table USRACLEXT, for example using transaction SM30.</P><BR /> <P style="padding-left: 40px">The mapping of an SNC name to a user can also be done in transaction SU01. Keep in mind that in SU01 only a 1:1 mapping can be performed while in the table USRACLEXT more than one certificates can be mapped to one user.</P><BR /> <BR /> <BLOCKQUOTE><BR /> <P style="padding-left: 40px"><STRONG>Please note:</STRONG> 'SNC User ACL' is not a feature of the RFC Gateway itself.</P><BR /> </BLOCKQUOTE><BR /> <BR /> <HR /><BR /> <BR /> &nbsp;<BR /> <P style="text-align: right"><A href="https://blogs.sap.com/2021/01/27/rfc-gateway-security-part-2-reginfo-acl/" target="_blank" rel="noopener noreferrer">Next --&gt;</A></P><BR /> &nbsp; 2021-01-26T09:05:26+01:00 https://community.sap.com/t5/enterprise-resource-planning-blogs-by-sap/sap-build-apps-and-bapis-rfc-meets-web/ba-p/13555549 SAP Build Apps and BAPIs: RFC meets Web 2023-04-02T12:17:56+02:00 Gunter https://community.sap.com/t5/user/viewprofilepage/user-id/727 <H2 id="toc-hId-962139719"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-164241.jpg" /><EM>"RFC meets Web"</EM></H2><BR /> <H3 id="toc-hId-894708933">Enable all your RFC functions for web consumption without development?</H3><BR /> Today, I'm excited to share a new thing: A proxy on SAP BTP that translates from REST to SAP RFC calls, making it possible to use BAPIs and RFC-enabled function modules on <STRONG>older SAP ECC</STRONG> or S/4HANA systems.<BR /> <BR /> This solution is particularly useful for SAP ERP users who are looking to integrate with systems that lack the new OData APIs that are only available on newer S/4HANA systems. With the REST-to-RFC proxy, RFC meets web, creating a seamless integration experience that unlocks the full potential of your SAP ecosystem.<BR /> <BR /> <STRONG>Benefits:</STRONG><BR /> <UL><BR /> <LI>Protect your past investment: Use your function modules for the web</LI><BR /> <LI>RFC modules turned into synchronous REST APIs</LI><BR /> <LI>No further development work</LI><BR /> <LI>Secured communication through SAP BTP destinations</LI><BR /> </UL><BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-160900-1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 1: Outline of solution - it works with any RFC function module (Y/Z-RFC modules included)</P><BR /> In this blog post, we'll take a closer look at how this proxy works, the benefits it provides, and the impact it can have on your SAP integration projects. So, let's dive in and discover the possibilities of web meets RFC!<BR /> <H2 id="toc-hId-569112709">Solution approach</H2><BR /> SAP BTP offers the destination service to define ways to connect to systems. Keeping destinations separate from applications makes them reusable and easy to maintain. They come in several flavors like:<BR /> <OL><BR /> <LI>HTTP - for anything like REST, OData-REST, HTML and the like.</LI><BR /> <LI>LDAP - Lightweight Directory Access Protocol to lookup information in a network. Often used for organizational data of entities and persons.</LI><BR /> <LI>MAIL - to send emails to an SMTP server</LI><BR /> <LI>RFC - Remote Function Call, this is what we look at for the cloud connector-facing side.</LI><BR /> </OL><BR /> From here we define the first destination to the <A href="https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/cloud-connector" target="_blank" rel="noopener noreferrer">cloud connector</A> (CC) as RFC. You need to white-list the function modules you plan to use in your cloud connector instance.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-165040.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 2: Example of an RFC destination. The ashost is as defined in your CC.</P><BR /> I use this destination in the Java HTTPServlet. On the consumption side you'll need another destination that you can use for e.g. SAP Build Apps and which is provided by the HTTPServlet. If you secure it with OAuth2 the config could look like that.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-165543.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 3: REST destination for consumption of BAPIs or RFC functions in general.</P><BR /> Since I use xsuaa for authentication and authorization I've defined 2 scopes to allow for display and change authorization.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-02-170311.jpg" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 4: POST and GET related scopes to be assigned to relevant users for consumption.</P><BR /> The difference between the two is that the POST will trigger a BAPI.commit and therefore posts data in your S/4HANA or ECC system while the GET doesn't. Of course it depends on how you've designed your ABAP code - standard BAPIs will adhere to this approach.<BR /> <H2 id="toc-hId-372599204">SAP Build Apps demo: Change material master</H2><BR /> Enough talk! Let's see a demo built with SAP Build Apps. It uses 3 BAPIs:<BR /> <OL><BR /> <LI>BAPI_MATERIAL_GETLIST - To search for materials and get them in a list</LI><BR /> <LI>BAPI_MATERIAL_GETALL - To retrieve the details of a selected material</LI><BR /> <LI>BAPI_MATERIAL_SAVEDATA - To change some fields in the material master</LI><BR /> </OL><BR /> There is no development done on both backend and frontend.<BR /> <H3 id="toc-hId-305168418">1. Mobile application</H3><BR /> <IFRAME id="kaltura_player_1_p5s5dr9z" src="https://sapvideoa35699dc5.hana.ondemand.com/?entry_id=1_2wkpiuv2" allowfullscreen="true" webkitallowfullscreen="" mozallowfullscreen="" width="625px" height="360px" frameborder="0"></IFRAME><BR /> <H3 id="toc-hId-108654913">2. SAP Build and S/4HANA Backend</H3><BR /> <IFRAME id="kaltura_player_1_p5s5dr9z" src="https://sapvideoa35699dc5.hana.ondemand.com/?entry_id=1_upydyozz" allowfullscreen="true" webkitallowfullscreen="" mozallowfullscreen="" width="625px" height="360px" frameborder="0"></IFRAME><BR /> <H2 id="toc-hId--216941311">Solution Architecture</H2><BR /> Below are the schematics for using the REST to RFC proxy running on BTP Cloud Foundry.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/04/スクリーンショット-2023-04-01-220657-1.png" /></P><BR /> <P class="image_caption" style="text-align: center;font-style: italic">Image 2: Solution architecture for REST-RFC proxy on SAP BTP Cloud Foundry</P><BR /> I'll explain the technical details in a second blog if you are interested to create such a proxy on BTP for yourself.<BR /> <H2 id="toc-hId--413454816">Conclusion</H2><BR /> And there it is: A proxy that opens all your RFC developments to the web in a secured manner. Hope it is useful!<BR /> <BR /> Check my <A href="https://blogs.sap.com/2023/04/04/rfc-meets-the-web-building-the-proxy/" target="_blank" rel="noopener noreferrer">second blog</A> for the technical details on how you can design the proxy on SAP BTP. 2023-04-02T12:17:56+02:00 https://community.sap.com/t5/technology-blogs-by-members/calling-a-sap-pi-po-rfc-integration-from-java-with-jco-library/ba-p/13578451 Calling a SAP PI/PO RFC integration from Java with JCo Library 2023-09-14T01:24:37+02:00 rsedatgoc https://community.sap.com/t5/user/viewprofilepage/user-id/702931 Hello everyone,<BR /> <BR /> We needed to call SAP PI/PO RFC integration with Java according to a customer's need. I was able to call functions from SAP using JCo before, but I had not worked on triggering the SAP PI/PO RFC sender. After some research, I found out how to do it and I wanted to share it with you.<BR /> <BR /> Before we write our Java code, we have a small but necessary step to do.<BR /> <OL><BR /> <LI><SPAN class="HwtZe" lang="en"><SPAN class="HwtZe" lang="en"><SPAN class="HwtZe" lang="en"><SPAN class="jCAhz ChMk0b"><SPAN class="ryNqvb">First of all, you need to download the JCo driver for your operating system.</SPAN></SPAN> <SPAN class="jCAhz ChMk0b"><SPAN class="ryNqvb">It is important to review the installation.html page located in the javadoc folder in the driver archive you downloaded.</SPAN></SPAN> <SPAN class="jCAhz ChMk0b"><SPAN class="ryNqvb">Actions to be taken according to your operating system are written on the HTML page. (<A href="https://support.sap.com/en/product/connectors/jco.html" target="_blank" rel="noopener noreferrer">SAP JCo Page</A>)</SPAN></SPAN></SPAN></SPAN></SPAN></LI><BR /> <LI>You need to add "<STRONG>jco.allow_non_abap_partner</STRONG>" parameter to the VM parameter of SAP PI/PO instance. You can review this SNote showing how to add a parameter. (<A href="https://me.sap.com/notes/1729203" target="_blank" rel="noopener noreferrer">1729203 - Support for communication with external RFC server</A>)</LI><BR /> <LI>Next step is create a RFC sender channel. You can create a standart RFC sender channel. But you have to enable Advanced Mode. Also you need to unchecked Verify Sender System parameter.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/verify_sender_system_unchecked-1.png" /></P><BR /> My channel 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/09/rfc_sender_adapter_configuration-1.png" height="439" width="744" /></P><BR /> &nbsp;</LI><BR /> <LI>Also we need to create an RFC integration. I imported a function to ESR from SAP which I will call from Java.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/imported_object.png" height="71" width="288" /></P><BR /> Then I created an ICO with that function.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/rfc_integration.png" /></P><BR /> &nbsp;</LI><BR /> </OL><BR /> If everything is okay, let's start!<BR /> <BR /> First, we need to define <STRONG>SAP.jcoDestination</STRONG> file for Repository. You can fill this template with your SAP system information for <STRONG>SAP.jcoDestination</STRONG> file.<BR /> <PRE class="language-abap"><CODE>jco.client.ashost=sap_application_server_host<BR /> jco.client.sysnr=sap_system_number<BR /> jco.client.client=sap_system_client_number<BR /> jco.client.user=sap_user<BR /> jco.client.passwd=sap_user_password<BR /> jco.client.lang=sap_language</CODE></PRE><BR /> Then, we have to create <STRONG>SAP_PO.jcoDestination</STRONG> file for communicate with SAP PI/PO. You can fill this template with your PO system information for <STRONG>SAP_PO.jcoDestination</STRONG> file.<BR /> <PRE class="language-abap"><CODE>jco.client.type=E<BR /> jco.client.gwhost=your_po_host<BR /> jco.client.gwserv=your_po_gateway<BR /> jco.client.tpname=PO_RFC_SND<BR /> jco.destination.repository_destination=repository_file_name</CODE></PRE><BR /> The <STRONG>jco.client.tpname</STRONG> parameter represents the Program ID parameter on the RFC sender channel. I write <STRONG>PO_RFC_SND</STRONG> to the value of this parameter because I write <STRONG>PO_RFC_SND</STRONG> to the Program ID value in the RFC channel.<BR /> <BR /> The value of <STRONG>jco.destination.repository_destination</STRONG> parameter must be SAP Repository file name. We defined the name of the file as <STRONG>SAP.jcoDestination</STRONG> in this blog. Therefore, we write <STRONG>SAP</STRONG> to the value of the jco.destination.repository_destination parameter.<BR /> <BR /> After the files are created, your project folder should look like this. (<EM><STRONG>The .jcoDestination files must be in the same place as your project.</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/09/sap_pi_rfc_project_structure.png" height="226" width="402" /></P><BR /> <STRONG>Let's code! </STRONG><BR /> <BR /> First, you have to add sapjco3.jar as external library to your project. If you done, you can continue next step.<BR /> <BR /> Define a JCoDestination variable. We have to write SAP_PO in <STRONG>getDestination</STRONG> method. Because our PO destination configuration file name is <STRONG>SAP_PO.jcoDestination</STRONG>. (If you named the file differently, use the name you typed. Don't forget! The file extension must be <STRONG>.jcoDestination</STRONG>. )<BR /> <PRE class="language-java"><CODE>JCoDestination dest = JCoDestinationManager.getDestination("SAP_PO");</CODE></PRE><BR /> We have to define JCoFunction variable. After that, we will use getFunction method with function name which we want to call. I will use "RFC_FUNCTION_SEARCH" function.<BR /> <PRE class="language-java"><CODE>JCoFunction function = dest.getRepository().getFunction("RFC_FUNCTION_SEARCH");<BR /> </CODE></PRE><BR /> Now, we need to set import parameters of RFC_FUNCTION_SEARCH function. You can see parameters of the function with SE37 tcode in SAP system.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/se37_import.png" height="245" width="491" /></P><BR /> I can see only FUNCNAME parameter is mandatory. I want to get all Z* named functions from SAP system therefore I assigned "Z*" to the FUNCNAME parameter.<BR /> <PRE class="language-java"><CODE>function.getImportParameterList().setValue("FUNCNAME","Z*");</CODE></PRE><BR /> I am running the function.<BR /> <PRE class="language-java"><CODE>function.execute(dest);</CODE></PRE><BR /> If you want to get result after execute the function, you can do with below code.<BR /> <PRE class="language-java"><CODE>String result = function.getTableParameterList().toJSON();<BR /> System.out.println(result);</CODE></PRE><BR /> Result;<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/function_result.png" height="95" width="491" /></P><BR /> &nbsp;<BR /> <PRE class="language-java"><CODE>package com.example;<BR /> <BR /> import com.sap.conn.jco.JCoDestination;<BR /> import com.sap.conn.jco.JCoDestinationManager;<BR /> import com.sap.conn.jco.JCoException;<BR /> import com.sap.conn.jco.JCoFunction;<BR /> <BR /> import java.io.IOException;<BR /> public class Main {<BR /> <BR /> public static void main(String[] args) throws IOException, JCoException {<BR /> <BR /> // Define a JCoDestination variable. We have to write SAP_PO in getDestination method.<BR /> // Because our PO destination configuration file name is SAP_PO.jcoDestination.<BR /> // (If you named the file differently, use the name you typed. Don't forget! The file extension must be .jcoDestination. )<BR /> JCoDestination dest = JCoDestinationManager.getDestination("SAP_PO");<BR /> <BR /> //We can define the function which we want to call. I will use "RFC_FUNCTION_SEARCH" function.<BR /> JCoFunction function = dest.getRepository().getFunction("RFC_FUNCTION_SEARCH");<BR /> <BR /> //Now, we need to set import parameters of RFC_FUNCTION_SEARCH function.<BR /> // You can see parameters of the function with SE37 tcode in SAP system.<BR /> function.getImportParameterList().setValue("FUNCNAME","Z*");<BR /> <BR /> //Execute the function<BR /> function.execute(dest);<BR /> <BR /> //Print result<BR /> String result = function.getTableParameterList().toJSON();<BR /> System.out.println(result);<BR /> <BR /> }<BR /> <BR /> }<BR /> </CODE></PRE><BR /> &nbsp;<BR /> <BR /> When you call the RFC with Java, you can see the message in Message Monitor.<BR /> <P style="overflow: hidden;margin-bottom: 0px"><IMG class="migrated-image" src="https://community.sap.com/legacyfs/online/storage/blog_attachments/2023/09/rfc_message_monitoring.png" /></P><BR /> &nbsp;<BR /> <H3 id="toc-hId-1093157915">Conclusion</H3><BR /> In summary, with this blog you can call the RFC integrations you developed in PI/PO with Java using the JCO library. In addition, based on this example, you can also call the function from SAP without PI/PO. You can use the <STRONG>SimpleCall.java</STRONG> example in the JCO file you downloaded.<BR /> <BR /> &nbsp;<BR /> <BR /> Thank you for reading. 2023-09-14T01:24:37+02:00 https://community.sap.com/t5/technology-blogs-by-members/import-data-connection-to-sap-s-4hana-in-sap-analytics-cloud-technical/ba-p/13697364 Import Data Connection to SAP S/4HANA in SAP Analytics Cloud : Technical Configuration 2024-05-10T12:04:30.942000+02:00 Utkarsh_goel123 https://community.sap.com/t5/user/viewprofilepage/user-id/166457 <P>In this blog we’ll discuss complete steps for Import data connection from S/4 hana on-premise system to SAP Analytics Cloud . The Operating system we are using on which S/4 Hana system is installed is SUSE Linux SP 15.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_26-1715328017346.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108457i04372F5188423BC5/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_26-1715328017346.png" alt="Utkarsh_goel123_26-1715328017346.png" /></span></P><P>&nbsp;</P><P>&nbsp;</P><P>Here, Our Data source is S/4 Hana from which the SAP Analytics Cloud is connected using the SAP Analytics Cloud Agent and SAP Cloud Connector.</P><P>It is recommended that the Cloud Connector,&nbsp;<SPAN>SAP Analytics Cloud</SPAN>&nbsp;agent, and the SAP Java Connector (JCo) are installed together on a dedicated server, and not a personal computer. This helps to ensure that multiple users can use an import data connection without experiencing slowness or downtime.</P><P>The SAP Analytics Cloud Agent Simple Deployment Kit allows you to quickly get your import data connections working.</P><P>The simple deployment kit is only supported on Windows 64-bit operating systems. If you have a different server, such as Linux, you'll need to install and configure the agent manually.</P><P>If we have windows Environment, then the SAP Analytics Cloud Agent Simple Deployment Kit is preferred. More details can be found in the below link.</P><P><A href="https://help.sap.com/docs/SAP_ANALYTICS_CLOUD/00f68c2e08b941f081002fd3691d86a7/c4751c8f9d0049a68d4202ebfc34ebe7.html" target="_blank" rel="noopener noreferrer">SAP Analytics Cloud Agent Simple Deployment Kit | SAP Help Portal</A></P><P>For Linux Environment we have to install SAP JVM, SAP Cloud Connector, Tomcat Apache server, SAC Agent, Java Connector.</P><P>Below are the steps for Import Data connection for On-premise S/4 HANA systems -</P><OL><LI>SAP JVM 8.1 and JDK installation on the linux server</LI><LI>Install SAP Cloud Connector on the same linux server.</LI><LI>Installing Tomcat Apache server</LI><LI>Installing and configuring Java connector (Jco)in Tomcat .</LI><LI>Installing and configuring SAP Analytics Cloud Agent .</LI><LI>Configuration and Connection steps in SAC portal</LI></OL><H3 id="toc-hId-1123603390">&nbsp;</H3><H3 id="toc-hId-927089885"><STRONG>1. SAP JVM 8.1 installation on the same linux server</STRONG></H3><P>Download the SAP JVM from the below link:</P><P><A href="https://tools.hana.ondemand.com/#cloud" target="_blank" rel="noopener nofollow noreferrer">https://tools.hana.ondemand.com/#cloud</A></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_27-1715328017356.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108459i398BCD78CD8AB1B3/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_27-1715328017356.png" alt="Utkarsh_goel123_27-1715328017356.png" /></span></P><P>Download the rpm file compatible for linux 86x64 - <A href="https://tools.hana.ondemand.com/additional/sapjvm-8.1.095-linux-x64.rpm" target="_blank" rel="noopener nofollow noreferrer"><BR />sapjvm-8.1.095-linux-x64.rpm</A>&nbsp;(<A href="https://tools.hana.ondemand.com/additional/sapjvm-8.1.095-linux-x64.rpm.sha1" target="_blank" rel="noopener nofollow noreferrer">sha1</A>)</P><P>Move the file to the server and run the below command to install SAP JVM</P><P>rpm -i &lt;file_name&gt;.rpm</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_28-1715328017360.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108458i6D388AB613A2FD7F/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_28-1715328017360.png" alt="Utkarsh_goel123_28-1715328017360.png" /></span></P><P>Also it is recommended to install the openjdk packages on SUSE linux .</P><P>Run command ‘zypper install java’</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_29-1715328017368.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108466i2C28DBEBC5343ADE/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_29-1715328017368.png" alt="Utkarsh_goel123_29-1715328017368.png" /></span></P><P>&nbsp;</P><P>To check the verison of openjdk installed.</P><P>Run command 'java –version'</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_30-1715328017370.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108463i51A9F4314BA743B0/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_30-1715328017370.png" alt="Utkarsh_goel123_30-1715328017370.png" /></span></P><H3 id="toc-hId-730576380"><STRONG>2. Install SAP Cloud Connector on the same linux server.</STRONG></H3><P>To download the SAP Cloud Connector go to the below link :</P><P><A href="https://tools.hana.ondemand.com/#cloud" target="_blank" rel="noopener nofollow noreferrer">https://tools.hana.ondemand.com/#cloud</A></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_31-1715328017379.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108467iA8AF031804F52E2A/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_31-1715328017379.png" alt="Utkarsh_goel123_31-1715328017379.png" /></span></P><P>&nbsp;</P><P>Download the zip file for Linux x86_64 Architechture and move the downloaded file to the server.</P><P>Now, unzip the file and install the rpm package for cloud connector as below.</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_32-1715328017381.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108471i59685BA67E5A6062/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_32-1715328017381.png" alt="Utkarsh_goel123_32-1715328017381.png" /></span></P><P>Cloud connector is installed now.</P><P>To open the SCC, enter: https://&lt;hostname&gt;:8443 in a browser, where the &lt;hostname&gt; is the hostname of the machine on which the connector is installed, and the port number is the one configured during installation. The default port number is 8443</P><P>By default Login Credentials are :</P><P>Username : Administrator</P><P>Password : manage</P><P>After the fist login , It prompts you to change password for the Administrator User.</P><H6 id="toc-hId-921311032">Now Add the SAC subaccount to the cloud connector:</H6><P>&nbsp;Click on “Add subaccount” and enter the details SAC subaccount , which you can find on SAP Analytics Cloud.</P><P>To find the Subaccount details of SAP Analytics Cloud :</P><P>You must use a System Owner account to perform the following steps. If you don't know who the system owner is, log on to&nbsp;<SPAN>SAP Analytics Cloud</SPAN>&nbsp;and from the side navigation, choose&nbsp;<SPAN><STRONG>&nbsp;Security</STRONG></SPAN><SPAN>&nbsp;&gt;&nbsp;</SPAN><SPAN><STRONG>Users</STRONG></SPAN>.&nbsp;</P><P>&nbsp;</P><UL><LI>Log on to&nbsp;SAP Analytics Cloud.</LI><LI>From the side navigation, choose&nbsp;<STRONG>System</STRONG>&nbsp;&nbsp;<STRONG>&gt;&nbsp;Administration</STRONG>.</LI><LI>Switch to the&nbsp;<STRONG>Data Source Configuration</STRONG>&nbsp;tab.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_35-1715328017388.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108478iCB8E7FB44A866FA4/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_35-1715328017388.png" alt="Utkarsh_goel123_35-1715328017388.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-337549370">3.<STRONG>Installing Tomcat&nbsp; Apache Server : </STRONG></H3><P>&nbsp;</P><UL><LI>Create a directory named tomcat in the /opt folder:</LI><LI>Go to the Apache Tomcat 8 Download page by clicking this&nbsp;<A title="link" href="https://tomcat.apache.org/download-80.cgi" target="_blank" rel="noopener nofollow noreferrer">https://tomcat.apache.org/download-80.cgi</A>&nbsp; Place your cursor under 8.5.65 Binary Distributions, right-click on the tar file and select the copy link address from the menu that appears (as shown in the picture below). At the time of writing, Tomcat 8 is the most recent edition, but you are free to use whatever version is most current.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_36-1715328017391.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108475iFBC4D04DAB84F3D1/image-size/medium?v=v2&amp;px=400" role="button" title="Utkarsh_goel123_36-1715328017391.png" alt="Utkarsh_goel123_36-1715328017391.png" /></span></P><UL><LI>Download the file from wget</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_37-1715328017392.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108476iCF815F783BA5FAD0/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_37-1715328017392.png" alt="Utkarsh_goel123_37-1715328017392.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_38-1715328017397.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108482i296DAF30D2E5D3CF/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_38-1715328017397.png" alt="Utkarsh_goel123_38-1715328017397.png" /></span></P><UL><LI>Extract the tar.gz file</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_39-1715328017400.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108483i2C58DD63B1A721BE/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_39-1715328017400.png" alt="Utkarsh_goel123_39-1715328017400.png" /></span></P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_40-1715328017402.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108481iB2C9E5E6C7F9A6FD/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_40-1715328017402.png" alt="Utkarsh_goel123_40-1715328017402.png" /></span></P><UL><LI>Starting Tomcat apache server</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_41-1715328017407.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108488i44A22E817C1E26AB/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_41-1715328017407.png" alt="Utkarsh_goel123_41-1715328017407.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId-141035865"><STRONG>4.Installing and configuring Java connector (Jco)in Tomcat .</STRONG></H3><P>&nbsp;</P><UL><LI>Download SAP Java connector from SAP support portal -&gt; Software downloads</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_42-1715328017408.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108487i088448E388E29408/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_42-1715328017408.png" alt="Utkarsh_goel123_42-1715328017408.png" /></span></P><UL><LI>On a Linux server, put the&nbsp;sapjco3.jar&nbsp;and&nbsp;libsapjco3.so&nbsp;in the&nbsp;lib&nbsp;folder of Apache Tomcat.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_43-1715328017420.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108489i72B35E60F944ED22/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_43-1715328017420.png" alt="Utkarsh_goel123_43-1715328017420.png" /></span></P><P>&nbsp;</P><H3 id="toc-hId--55477640"><STRONG>5. Installing and configuring SAP Analytics Cloud Agent .</STRONG></H3><P>&nbsp;</P><P>It is recommended, but not mandatory, that the Cloud Connector,&nbsp;<SPAN>SAP Analytics Cloud</SPAN>&nbsp;agent, and the SAP JCO are installed together on a dedicated server, and not a personal computer. This helps to ensure that multiple users can use an import data connection without experiencing slowness or downtime.</P><P>Modifying the Cloud Connector’s embedded web application and deploying the agent to it is not supported.</P><UL><LI><SPAN>Download the&nbsp;SAP Analytics Cloud&nbsp;agent from the SAP Support Portal.</SPAN></LI></UL><P>The agent is available on the&nbsp;<A href="https://launchpad.support.sap.com/#/softwarecenter" target="_blank" rel="noopener noreferrer">SAP Software Downloads</A>&nbsp;page. Expand&nbsp;<SPAN><STRONG>By Category</STRONG></SPAN>, select&nbsp;<SPAN><STRONG>SAP Cloud Solutions</STRONG></SPAN><SPAN>&nbsp;&gt;&nbsp;<STRONG>SAP ANALYTICS CLOUD CONN</STRONG>&nbsp;&gt; <STRONG>SAP ANALYTICS CLOUD CONN 1.0</STRONG>&nbsp;&gt;&nbsp;<STRONG>SAP ANALYTICS CLOUD AGENT 1.0</STRONG></SPAN>&nbsp;and download the latest version.</P><UL><LI><SPAN>Unzip the downloaded file and rename the&nbsp;</SPAN><SPAN>WAR</SPAN><SPAN>&nbsp;file to&nbsp;</SPAN><SPAN>C4A_AGENT.war</SPAN><SPAN>.</SPAN></LI><LI><SPAN>Extract the package and copy the file&nbsp;</SPAN><SPAN>C4A_AGENT.war</SPAN><SPAN>&nbsp;to your Tomcat&nbsp;</SPAN><SPAN>webapps</SPAN><SPAN>&nbsp;directory.</SPAN><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_44-1715328017443.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108495i79829B6D2DD05368/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_44-1715328017443.png" alt="Utkarsh_goel123_44-1715328017443.png" /></span></LI></UL><P>The agent will automatically deploy when Tomcat is restarted.&nbsp;</P><UL><LI><SPAN>Create a user for the&nbsp;SAP Analytics Cloud&nbsp;agent and assign the&nbsp;</SPAN>Services<SPAN>&nbsp;role to the user.</SPAN></LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_45-1715328017453.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108494i4B301691F87B4890/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_45-1715328017453.png" alt="Utkarsh_goel123_45-1715328017453.png" /></span></P><P>&nbsp;</P><UL><LI>The user credentials will be needed later for setting up the connection to&nbsp;<SPAN>SAP Analytics Cloud</SPAN>.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_46-1715328017454.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108493iE22515C3982ABCB0/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_46-1715328017454.png" alt="Utkarsh_goel123_46-1715328017454.png" /></span></P><P>&nbsp;</P><UL><LI><SPAN>Restart the Tomcat application server for the settings to take effect.</SPAN></LI><LI><SPAN>Test if the installation was successful, by opening the following URL in your browser:&nbsp;</SPAN><SPAN>http://</SPAN>&lt;Host&gt;<SPAN>:</SPAN>&lt;Port&gt;<SPAN>/C4A_AGENT/deploymentInfo</SPAN></LI></UL><P>The version of the&nbsp;<SPAN>SAP Analytics Cloud</SPAN>&nbsp;agent installed is displayed.</P><P>&nbsp;</P><H3 id="toc-hId--251991145"><STRONG>6. Configuration and Connection steps in SAC portal</STRONG></H3><P>&nbsp;</P><UL><LI>Add the Data source in System &gt; Administration &gt; on-premise data sources</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_47-1715328017463.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108499i0B612F42A9660FB0/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_47-1715328017463.png" alt="Utkarsh_goel123_47-1715328017463.png" /></span></P><P>&nbsp;</P><UL><LI>Check connection configuration , It should be green.</LI></UL><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_48-1715328017470.png" style="width: 999px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108500i0DBF023DFAAAF316/image-size/large?v=v2&amp;px=999" role="button" title="Utkarsh_goel123_48-1715328017470.png" alt="Utkarsh_goel123_48-1715328017470.png" /></span></P><P>&nbsp;</P><UL><LI>From the side navigation, choose&nbsp;<P>&nbsp;</P><STRONG>Connections &gt;&nbsp;</STRONG>&nbsp;<STRONG>(Add Connection)</STRONG>.</LI></UL><P>The&nbsp;<STRONG>Select a data source</STRONG>&nbsp;dialog will appear.</P><UL><LI>Expand&nbsp;<STRONG>Acquire Data</STRONG>&nbsp;and select&nbsp;<STRONG>SAP S/4HANA</STRONG>.</LI><LI>In the&nbsp;<STRONG>New SAP S/4HANA Connection</STRONG>&nbsp;dialog, do the following:</LI></UL><OL><OL><LI>In the&nbsp;<STRONG>Connection Information</STRONG>&nbsp;section, add a&nbsp;<STRONG>Connection Name</STRONG>&nbsp;and&nbsp;<STRONG>Description</STRONG>.</LI><LI>If you are connecting to an&nbsp;SAP S/4HANA&nbsp;on-premise system, select&nbsp;<STRONG>Connect to an On-Premise OData service</STRONG>, and then select the&nbsp;<STRONG>Location</STRONG>&nbsp;of your Cloud Connector from the list.</LI><LI>Enter the&nbsp;<STRONG>Data Service URL</STRONG>&nbsp;published during your configuration</LI></OL></OL><UL><LI>Select the authentication type.</LI><LI>Enter the&nbsp;<STRONG>User Name</STRONG>&nbsp;and&nbsp;<STRONG>Password</STRONG>&nbsp;of the user you want to import data from.</LI><LI>Choose&nbsp;<STRONG>Create</STRONG>.</LI></UL><P>The new connection is added to the list of connections on the&nbsp;<STRONG>Connections</STRONG>&nbsp;screen.</P><P>&nbsp;</P><P><span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Utkarsh_goel123_51-1715328017474.png" style="width: 400px;"><img src="https://community.sap.com/t5/image/serverpage/image-id/108502iF36599FE6D0E2DC9/image-size/medium?v=v2&amp;px=400" role="button" title="Utkarsh_goel123_51-1715328017474.png" alt="Utkarsh_goel123_51-1715328017474.png" /></span></P><H4 id="toc-hId--319421931">Conclusion :</H4><P>Import Data Connection to S/4Hana on-premise system in SAP Analytics Cloud has been established successfully.</P><P>&nbsp;</P> 2024-05-10T12:04:30.942000+02:00