一个 SaaS 软件同本地部署 On-Premises 系统集成的实际项目案例分享

最近有朋友在微信上问我本文标题这个需求,即如何在 SAP Cloud for Customer 这个 CRM SaaS 软件里,调用本地部署 On-Premises 系统里的 API. 正好笔者曾经参加过 SAP 和沈阳自动化研究所合作设计的一个工业 4.0 示范系统 POC 中,曾经用到了这个技术,本文就来把这个项目中用到的技术方案给大家做一个分享。

关于这个 POC 的详情,在 SAP 中国研究院官方公众号这篇文章里有详细叙述:
SAP中国研究院&中科院沈阳自动化所重磅发布第三代自适应模块化智能生产解决方案
SAP 中国研究院和中科院沈阳自动化研究所(沈自所)联合打造了一套自适应模块化智能生产解决方案,作为双方合作的第三代工业 4.0 智能制造解决方案,其生产组织形式采用世界领先的模块化生产概念,业务流程涵盖从个性化产品销售订单的创建到车间仓储和物料管理和生产执行与交付,在车间里传统的生产线被解耦为模块化生产单元,其机械结构、工业网络、生产工序可以根据产品设计的变化,现场设备状态,自适应完成重构。改造成本大大压缩,调整周期显著缩短。同时,实现了智能仓储系统、智能生产系统、智能机器人、智能 AGV 运输车辆等系统的高度集成和高效运转,这也是 SAP 最新提出的「从设计到运维(D2O,From Design to Operate)」的工业互联网全业务流程中的重要环节。

下面这个 POC 视频,是当时的项目兼产品经理,我的研究院同事 Cai Carol 制作的。视频最开头,展示的是从 SAP Cloud for Customer 里创建销售订单。SAP C4C 销售订单创建完毕之后,点击订单明细页面的一个按钮,触发 S/4HANA 的交货单(Outbound Delivery)创建,进而触发接下来的制造流程的执行。
其中 SAP Cloud for Customer 部分的定制开发是由笔者实现的,里面就涉及到了本文标题描述的场景,即 SAP Cloud for Customer 里直接调用 SAP S/4HANA 的 API. 整个定制开发部分均可在 C4C 的 Cloud Application Studio 里完成,这意味着 Partners 也可以完成类似场景的开发。
下面是具体的实现步骤。
(1) 首先在 S/4HANA 里开发一个 API,逻辑是接收从 SAP Cloud for Customer 传过来的 Sales Order ID,读出其包含的行项目,然后调用 SAP S/4HANA 的交货单创建函数,为这些行项目创建交货单。
用关键字 S/4HANA Outbound Delivery,一下子就搜索到了对应的 BAPI 名称:BAPI_OUTB_DELIVERY_CREATE_SLS.
很快写好了一个 report:在第 21 行硬编码了一个 SAP Cloud for Customer 的销售订单 ID,测试后发现没什么问题,将这个报表的源代码拷贝到一个新的 ABAP Class 里,稍作修改,将硬编码去掉,替换成从 SAP Cloud for Customer 传过来的销售订单 ID 即可。

在 SAP S/4HANA 里新建一个 SICF 服务节点,其实现 Class 指定成刚刚建好的包含了调用 BAPI_OUTB_DELIVERY_CREATE_SLS 的 ABAP Class. 每个 ABAP SICF 节点会自动生成一个 url,从而将其节点分配的 SICF ABAP Class 的业务逻辑通过 HTTP 的方式暴露给外界。
关于 ABAP SICF 的更多介绍,请参考我之前的文章:从 ABAP Netweaver 的 SICF 到 SAP Kyma 的 Lambda Function.
我们当时做 POC 的这台 S/4HANA 服务器,其 url 是可以直接被外网访问到的,所以省去了使用 SAP Cloud Connector 将其暴露给外网这一步。对于常规的 SAP ABAP On-Premises 平台上开发的 HTTP Service url,请参考我这篇文章将其暴露给公网使用:
使用 Java+SAP 云平台+SAP Cloud Connector 调用 ABAP On-Premise 系统里的函数
(2) 回到 SAP C4C,打开 Cloud Application Studio,对标准的 Sales Order BO 进行扩展,增添一个新的 Action.
准确的说,被扩展的 BO 名称应该为 CustomerQuote,因为根据 SAP C4C 帮助文档介绍,Sales ORder 和 Sales Quote 共用同一个 BO 模型 CustomerQuote,通过模型字段 Type Code 的不同值来区分。

对 CustomerQuote 进行扩展,创建一个新的 Action:triggerOutboundDelivery:

这个 Action 的实现逻辑当然就是调用前一步骤里创建好的,SAP S/4HANA 通过 SICF 暴露出来的 API.
在动手实现 Action 之前,我们还需要在 SAP C4C 里创建一些消费 S/4HANA API 所需要的模型。
Cloud Application Studio 里新建一个 External Web Service Integration:

Web Service 名称取为 JerryExternal,类型为 REST. URL 字段,填充成 S/4HANA API 的 url.

这个 Web Service 模型的创建,会同时自动创建一个 Communication Scenario,名称为 JerryExternalService:

基于该 Communication Scenario 创建一个新的 Communication Arrangement:

通过上图邮件菜单,打开 Communication Arrangement 的维护 UI:

将访问 S/4HANA API 所需的用户名和密码,维护到新建的 Communication Arrangement 里去:

最后,实现 CustomerQuote BO 扩展出来的 Action,在里面通过 C4C 标准的工具库函数 WebServiceUtilities.ExecuteRESTService,消费 S/4HANA API:

从上图 ABSL 实现代码,我们也能体会到 SAP 引入 Communication Scenario & Arrangement 这些模型带来的好处:
Code Over Configuration is better than Code Over Code - 基于配置编程优于硬编码。
如果 SAP S/4HANA API url 或者用户名和密码发生变化,我们只需修改 C4C 里 Communication Scenario 和 Arrangement 对应的配置即可,而无需重新编译 ABSL 代码本身。
最后,在 SAP C4C UI 上点击 Trigger Delivery 按钮后,触发我们在 BO 上自定义的 action:


上图是 SAP C4C ABSL 代码的单步调试,点击 Continue 之后,设置在 SAP S/4HANA SICF 实现类里的 ABAP 断点触发,调试器里能看到 SAP C4C Sales Order ID 已经成功传递到 SAP S/4HANA 端了。

之前我已经将 SAP C4C 端的销售订单,同步到了 SAP S/4HANA 端,且两个系统里销售订单的 ID 一致。因此,在 SAP S/4HANA 端,调用 S/4HANA 销售订单的读取 API,读到的是 SAP C4C 同步过来并存储到 S/4HANA 的销售订单数据。
本文介绍了 SAP C4C 如何通过定制开发,实现消费第三方系统 API 的需求。这里的第三方系统 API,可以是 SAP S/4HANA,SAP Business Technology Platform 或者其他任何系统的 API,是一种比较通用的二次开发方式,希望对大家有所帮助。
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/9a3cfa67000f9abe9ed828c31】。文章转载请联系作者。
评论