我正在开发一个 Wrapper/Bridge COBOL 程序,该程序处理程序调用并执行横切操作,如日志记录、安全检查等。
主要动机是检查消费者程序的安全访问是否有权调用生产者程序。
设桥接 COBOL 程序为 B1,生产者程序 P1 和消费者(客户端)C1。
当C1要调用P1时,它必须调用B1。然后,B1 检查可访问性。如果 C1 具有访问权限,则 B1 使用 C1 的数据调用 P1。
C1 -> B1 -> P1
这里B1和P1的联动部分是一样的。程序正在使用 EXEC CICS LINK 相互调用。
COMMAREA,
COMMAREA1 (DataSet Name)
01 COMMAREA-STRUCT,
03 a-field
03 another-field
...
客户端;
IDENTIFICATION DIVISION.
PROGRAM-ID. Client.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY COMMAREA1
PROCEDURE DIVISION
/* fill CommareaStruct with some values. */
....
/* call B1 Bridge */
EXEC CICS LINK PROGRAM (B1Bridge) NOHANDLE
COMMAREA (COMMAREA-STRUCT)
LENGTH (LENGTH OF COMMAREA-STRUCT)
END-EXEC
....
桥,
IDENTIFICATION DIVISION.
PROGRAM-ID. B1Bridge.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
COPY COMMAREA1
PROCEDURE DIVISION
...
/* access control */
/* logging */
...
/* pass data to P1*/
EXEC CICS LINK PROGRAM (P1) NOHANDLE
COMMAREA (COMMAREA-STRUCT)
LENGTH (LENGTH OF COMMAREA-STRUCT)
END-EXEC
....
生产者;
IDENTIFICATION DIVISION.
PROGRAM-ID. P1
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
COPY COMMAREA1
PROCEDURE DIVISION
....
*doing some business with data in COMMAREA1
...
当我尝试上述操作时,我收到了 Bridge Program B1 的编译时警告;
“引用了 COMMAREA-STRUCT 或其下属之一,但 COMMAREA-STRUCT 是一个没有可寻址性的 LINKAGE SECTION 项目。此引用将不会在执行时成功解析。”
这是什么意思?我应该如何将 B1 的链接部分传递给 P1 的链接部分?
当我这样尝试时,我在运行时得到了 EIBRESP:22 和 EIBRESP2:26(逗号长度错误)。
- 编辑 -
我想我应该提供更多细节;
主要动机;
实际上有两家公司,COM1 和 COM2。 COM2 多年来一直是 COM1 的附属公司。
COM1 和 COM2 分别具有 CICS1 和 CICS2。 COM2 客户端程序使用 COM1 生产者程序。 COM2 客户端从不直接调用 COM1 生产者。 COM2 客户端将数据放入 COMMAREA-STRUCT 并远程调用通用 Cobol 程序(让它成为 GCP)。 COMMAREA-STRUCT 还具有“生产者程序名称”字段,GCP 可以通过该字段确定要调用哪个程序。因此,GCP 从 COMMAREA-STRUCT 导出数据并映射到生产者的字段。 GCP 通过寻址动态执行映射操作(对于每个生产者来说并不特殊)。生产者执行后,GCP 获取结果并通过 COMMAREA-STRUCT 传回给客户端。
该系统在几年前就是这样设计的。 COM2 的客户有数千个,COM1 的生产者有数千个。
现在,COM2 要与 COM1 分开。因此 COM1 不想再授予对所有 COM1 资源(生产者)的完全访问权限。因此,COM1 想要在 CICS1 前面放置一个新的 cics,它将是一个仅在本地运行 B1 Bridge 程序的处理程序 CICS。这也与网络安全和公司政治决策有关。
暂时将公司彼此分开,客户和生产商都不应受到影响。所以,问题应该在 GCP-Bridge 层解决。
这就是为什么,B1 Bridge 对 COM2 客户端的行为应该像 GCP,应该检查可访问性(不知何故,我们应用了它)并且应该将来自客户端的所有数据传递给 GCP,而无需任何修改。
当前日志操作没有任何优先级。我们将在一段时间内专注于部分公司。
所以我非常感谢您的专家意见。
*我们不能使用 CALL 因为 B1 将在另一个 CICS 上并且无法访问 COM1 的 LOADLIB1 这就是为什么 B1 应该通过 EXEC CICS LINK 远程调用 GCP。
*不是通过逗号,而是通过 channel 对我来说听起来不错。我们将就此展开讨论。
*顺便说一下,我将检查 LENGHT OF 上的全字-半字冲突。你是对的。
*对于安全检查,我们将讨论“EXEC CICS QUERY SECURITY”。
*如上所述,我们不能修改抄写本。只有我们能改变的是,
EXEC CICS LINK PROGRAM (GCP)
到
EXEC CICS LINK PROGRAM (B1)
通过查找和替换在客户端上。因为有成千上万的客户。我们不想改变抄写本并触摸它们。
从这些细节来看,我认为问题变得更容易理解了。
最佳答案
在通过 EXEC CICS LINK
调用的 CICS COBOL 程序中,链接部分必须包含一个名为 DFHCOMMAREA
的 01 级结构。 .预编译器或 COBOL 编译器的 CICS 协处理器将生成适当的 USING
用于程序部门,因此程序可寻址到 DFHCOMMAREA
结构体。DFHCOMMAREA
将包含您正在调用的内容 COMMAREA-STRUCT
当你LINK
到目标程序。
处理您发现自己的情况的一种方法是修改您的字帖以删除 01 级结构名称,并要求所有客户在 COPY
之前编码自己的 01 级结构名称。陈述。在桥接器和生产者程序中,这个 01 级结构名称将是 DFHCOMMAREA
.
处理这种情况的另一种方法是避开 LINK
赞成动态CALL
.您必须包含 DFHEIBLK
作为 CALL
的第一个参数.
处理这种情况的另一种方法是避开一个或多个 CICS 容器的逗号区域。而不是在 LINK
上传递逗号区域您将传递一个 channel ,该 channel 将悬挂一个或多个容器,其中包含您希望传递的数据。
需要注意的是,您正在使用 LENGTH OF
您的逗号长度的特殊寄存器。专用寄存器是一个全字,但逗号区长度参数是一个半字。我怀疑这会让您感到悲伤,除非 IBM 生成代码来拦截该特定习语并将特殊寄存器移动到临时半字(不太可能但可能)。
更新:
从您的附加信息中可以明显看出您的任务是为现有程序(GCP)编写“直接替换”。
一种实用的方法可能是创建一个新的字帖,我们称之为 COMAREA2,它是 COMAREA1 的副本,但没有嵌入的 01 级结构名称。放置 COPY COMAREA2
紧跟在 DFHCOMMAREA
之后的声明01 B1 程序中的结构名称。
这并不理想,因为某处的文档必须明确说明对 COMAREA1 副本的更改必须反射(reflect)在 COMAREA2 中。像这样的手动过程当然会引入出错的可能性,但它确实让您不必修改任何 C1 或 P1 程序。
更优雅,如果它适合您,将尝试...
COPY COMAREA1 REPLACING == 01 COMMAREA-STRUCT== BY ==*01 COMMAREA-STRUCT==.
...在您的 B1 计划中。这将消除对上述建议的 COMAREA2 字帖的需要。如果这有效,您只需放置
COPY
DFHCOMMAREA
之后的声明01 结构层名称。
关于cobol - 如何在 COBOL 中将链接部分数据传递给另一个程序的链接部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38956306/