SAP Fiori @OData.publish 注解的工作原理解析

笔者前一篇文章 SAP Fiori 注解 @ObjectModel.readOnly 工作原理解析,介绍了 SAP Fiori 编程模型里 @ObjectModel.readOnly
注解的工作原理。SAP Fiori 注解,是 ABAP Programming Model for SAP Fiori 的重要概念之一。
所谓注解(annotation),Java 和 JavaScript 开发人员一定不会陌生。
类似的,CDS 注解允许 ABAP 开发人员,将 ABAP 和特定于组件的元数据添加到任何 CDS 实体的源代码中。
根据一致性和注解有效性的评估实现细节,SAP CDS view 的注解分为以下两类:
ABAP 注解:由 ABAP 运行时环境评估。
Component 注解:由相关的 SAP 框架进行评估。
开发人员可以在元数据扩展中使用注解,为 CDS 视图定义特定于客户的元数据,而无需修改 SAP 发布的标准 CDS 实体本身。使用元数据扩展时,可以覆盖数据定义中定义的特定注释值,或向实体添加额外的注释值。
注解可以添加在 CDS view 上或者 view field 上,下面是一个例子:
本文继续探讨另一个 注解 @OData.publish
的工作原理。
在 SAP 官网的 ABAP Programming Model for SAP Fiori 的帮助文档里,在 OData Annotations 目录下有对这个注解的介绍。

一旦加上了这个注解的 CDS view 激活时,会自动生成一个 OData 服务。

这个 OData 服务是如何自动生成的?这就是本文所要分享的内容。
SAP Fiori 编程模型支持一种新的 OData 服务的暴露方式,这种 OData 服务的模型定义,和运行时,基于 Service Adaptation Description Language 简称 SADL.
下面是一个例子:
使用 SAP ABAP Development Tool,打开 CDS 视图源代码编辑页面,将 OData 注解添加到 CDS 视图之后,就可以触发整个 DDL 源的激活。ABAP 开发工具将激活请求委托给 SADL 框架。SADL 生成若干个 SAP Gateway 构件(Artifacts),这些构件存储在应用服务器 AS ABAP 的后端,是 SAP Gateway hub 系统中激活和运行 OData 服务所必需的。

以上是通过 CDS view 暴露 OData 服务的理论知识。
假设我们对加了这个注解的 CDS view 激活后自动生成的 OData 服务的明细一无所知,从何处开始入手进行研究呢?
我创建了一个名为 zjerrytest20160311
的 view,然后加上这个注解,激活。根据我的经验,按照 SAP 惯例,自动生成的 OData 服务的名称应该也会包含 0311 这个字符串。

激活之后,我试着用 0311 作为关键字在 OData 服务的注册事务码/IWFND/MAINT_SERVICE 里搜索,果然搜到了对应生成的 OData 服务:

在笔者之前的文章 ABAP 编程语言中 Class(类) 的设计原理剖析 曾经提到 ABAP Netweaver 的注册表 TADIR,按照 0311 进行查询,发现 CDS view 激活之后,除了 OData 服务本身,还自动生成了下列这些对象:

IWMO: SAP Gateway Business Suite Enablement 对应的模型
IWSV: SAP Gateway Business Suite Enablement 对应的服务
CLAS: OData 服务的实现类 ZCL_ZJERRYTEST20160311
做个实验,当我把 OData.publish 的值设置为 false,再次激活,发现类型为 IWMO 和 IWSV 的对象从注册表 TADIR 中消失了,这再次印证了二者是注解 OData.publish 设置为 true 之后激活 CDS view 生成的。

那么如何研究 CDS view 激活时,这两个对象的自动生成逻辑呢?
打开事物码 ST05,进入跟踪模式,激活 CDS view,在数据库跟踪结果里果然发现了将自动生成的对象名称插入到注册表 TADIR 的 OPEN SQL 语句。

在 ABAP 里,在插入数据库表的 OPEN SQL 语句之前,必定有待插入数据的生成逻辑。点击 ST05 里蓝色的眼镜图标,自动跳转到 OPEN SQL 语句里。设置断点,激活 CDS view,断点触发:

从当前的调用栈往外追溯,发现在第 21 个调用栈帧,正是自动生成 OData 服务的地方:

CL_WB_DDLS_SECOBJ_HNDLR_SINGLE->IF_DDIC_WB_DDLS_SECOBJ_HANDLER~ON_ACTIVATION 这个方法首先根据 delta_state 判断出需要删除,新增或者更新的对象清单,分别存储在下图 12 到 14 行三个输出参数里。

举个例子,当我在一个已经激活过后的 CDS view 源代码里添加 @OData.publish:true 的注解,然后激活,此时该注解对于的 EDIT_STATE 为 N(New), 而其他的注解因为没有任何变化,被标记为 U(Unchanged).

此处会根据 EDIT_STATE 的值,进入对应的分支。

EDIT_STATE 值为 N 的分支,则执行 OData 服务的创建,通过 CL_SADL_GTK_ODATA_SERVICE_GEN 完成,后缀 GEN 代表 Generation.

从调试器里能看出,名称为 ZJERRYTEST20160311 的 OData 服务通过 create_via_exposure 方法被创建。完整的调用栈:

本文其实也是另一个具体的例子,在不了解一段逻辑(无论框架层面或者应用层面)的情况下,如何使用 ST05 这个工具来找到设置断点的代码位置,从而找到问题分析的突破口。
总结
本文从一个开发人员的视角,深入介绍了 SAP Fiori 注解 @OData.publish 的工作原理。同时也展示了如何通过事物码 ST05,自行定位到 ABAP 框架自动生成 OData 服务资源的准确代码位置。
版权声明: 本文为 InfoQ 作者【Jerry Wang】的原创文章。
原文链接:【http://xie.infoq.cn/article/c4c4bfc37d16eb4600930375a】。文章转载请联系作者。
评论