编写定制 EP 适配器

定制 EP 适配器是与事件绑定关联的 CICS® 程序,该程序 格式化并发出 事件绑定生成的事件。

关于此任务

如果 CICS 提供的 EP 适配器不满足您的事件处理需求,那么您可以编写自己的定制 EP 适配器以处理事件数据。

CICS 针对发出的每个事件调用 EP 适配器。 定制 EP 适配器的输入是当前通道,其中包含作为容器集合的 CICS 事件对象。 容器包括: DFHEP.CONTEXTDFHEP.DESCRIPTORDFHEP.ADAPTERDFHEP.ADAPTPARMDFHEP.CHAR.nnnnnDFHEP.DATA.nnnnn。 提供了 DFHEP.CONTEXTDFHEP.DESCRIPTORDFHEP.ADAPTPARM 容器的副本。 这些副本可以在 CICS发行版之间进行更改; 因此,您应该针对每个新的 CICS 发行版重新编译定制 EP 适配器。

除了发出的事件外,定制 EP 适配器还必须生成用于表明成功与否的指示。

过程

  1. 包含针对您的编程语言的事件上下文数据副本。
    此副本描述 DFHEP.CONTEXT 容器,此容器存储您的 EP 适配器正在处理的事件的上下文数据。
    • DFHEPCXD(针对汇编语言)
    • DFHEPCXO(针对 COBOL)
    • DFHEPCXL(针对 PL/I)
    • DFHEPCXH(针对 C)
  2. 包含针对您的编程语言的事件描述符副本。
    此副本描述 DFHEP.DESCRIPTOR 容器,此容器描述针对您的 EP 适配器正在处理的事件捕获的业务数据。
    • DFHEPDED(针对汇编语言)
    • DFHEPDEO(针对 COBOL)
    • DFHEPDEL(针对 PL/I)
    • DFHEPDEH(针对 C)
  3. 包含针对您的编程语言的 EP 适配器参数副本。
    此副本描述 DFHEP.ADAPTPARM 容器。
    • DFHEPAPD(针对汇编语言)
    • DFHEPAPO(针对 COBOL)
    • DFHEPAPL(针对 PL/I)
    • DFHEPAPH(针对 C)
  4. 使用事件上下文数据副本从 DFHEP.CONTEXT 容器获取上下文信息。
  5. 获取 EP 适配器定制数据。 DFHEP.ADAPTER 容器包含在 传递到定制适配器的数据 字段中指定的数据,该字段位于事件绑定的事件绑定编辑器的 适配器 选项卡中。
    注: 此容器中的数据限制为 EBCDIC 字符。
  6. 使用 EP 适配器参数配置副本从 DFHEP.ADAPTPARM 容器获取 EP 适配器参数。
    DFHEP.ADAPTPARM 容器中的一个重要信息项是发出可恢复性指示符 EPAP-RECOVER。 此容器还包含适配器名称 EPAP-ADAPTER-NAME。
  7. 定制适配器必须验证定制 EP 适配器的 DFHEP.ADAPTPARM 容器中的 EPAP-RECOVER 设置。
    EP 适配器必须以可恢复方式或不可恢复方式使用传输来发出事件。 如果该设置不是 EPAP-ANY-RECOVERABLE,那么必须遵从 EPAP-RECOVER 设置。 为支持同步发出,EP 适配器必须能够区分上下文容器中的 EPAP-RECOVER 设置指示的传输可恢复性需求。
    • 如果该字段设置为 EPAP-RECOVERABLE,那么 EP 适配器必须以可恢复方式写入传输。
    • 如果该字段设置为 EPAP-NON-RECOVERABLE,那么 EP 适配器能以可恢复方式写入传输。
    如果无法遵从可恢复性设置,那么必须终止适配器;否则,将无法正确实现事件的事务性需求。

    对于异步发出,该字段设置为 EPAP-ANY-RECOVERABLE。

  8. 使用事件描述符副本从 DFHEP.DESCRIPTOR 容器获取事件描述符。
    事件描述符包含一个用于说明描述符中数据项数的前缀,并且针对每个数据项均包含一个描述符。 数据项描述符包含业务数据项的名称及其类型。 数据项本身位于格式为 DFHEP.CHAR.nnnnnDFHEP.DATA.nnnnn的容器中,其中 nnnnn 是 5 数字的序号,指示从 00001开始捕获的数据的顺序。 DFHEP.CHAR.nnnnn 容器包含可打印 (字符) 格式的捕获数据,格式如事件规范中所请求。 DFHEP.DATA.nnnnn 容器包含未格式化的捕获数据。
  9. DFHEP.CHAR.nnnnnDFHEP.DATA.nnnnn 容器获取数据项。
    处理捕获的数据项。 例如,您可能希望将每个项写入 CICS 瞬时数据队列。
    注: 如果数据项不可用于数据捕获,那么相应的数据项容器在 CICS 事件对象中不存在。 例如,当 CAPTURESPEC 指定与导致事件的 API 命令上不存在的可选参数关联的捕获数据项时,可能发生这种情况。 相应的 DFHEP.CHAR.nnnnn 将存在于 CICS 事件对象中,但将包含一个或多个星号,每个缺少数据的字符都有一个星号。
  10. 格式化数据,然后发出事件。

    DESCRIPTOR 数组中的每个项都会定义已捕获的源数据的类型,以及在格式化此数据时所需的长度和类型。

    捕获的数据长度不能超过捕获数据项规范中指定的长度。 捕获的数据正好是在源数据区域中找到的数据。 如果捕获数据不可用,那么不会创建对应的 DFHEP.DATA 容器。

    所有数据类型均支持自动 (0) 格式长度。 使用自动格式长度时,同等的 EPDE 字段设置为 epde_formatLen_auto

    所有数字数据类型均支持自动格式精度,这会导致使用所指定数据类型所需的长度和精度。 使用自动格式精度时,同等的 EPDE 字段设置为 epde_formatPrec_auto

  11. 通过发出 EXEC CICS RETURNEXEC CICS ABEND 命令完成处理。

    除了发出的事件外,定制 EP 适配器还必须生成用于表明成功与否的指示。 无法发出事件的定制 EP 适配器必须以异常终止代码结束,以便 CICS 可以启动任何必需的恢复操作并增加相应的统计信息。

COBOL 语言的示例代码片段

此代码片段显示该过程中所述步骤的顺序。 其中不包含任何对 EP 适配器信息或数据项的处理。

******************************************************************
 Linkage section.                                                 
******************************************************************
 01 EPContext.                                                    
    copy dfhepcxo.                                                
 01 EPDescriptor.                                                 
    copy dfhepdeo.                                                
 01 EPAdapter          pic x(16).                                 
 01 EPAdaptparm                                                   
    copy dfhepapo.                                                
 01 EPData             pic x(32000).                              
******************************************************************
 Main-program section.                                            
******************************************************************
*                                                                 
     perform Initial-processing.                                  
*                                                                 
*    Process the data items                                       
     perform Process-data-item                                    
             varying ItemNum from 1 by 1                          
             until ItemNum > epde-itemcount.                      
*                                                                 
******************************************************************
* Any final EVENT PROCESSING code to go here                      
******************************************************************
*                                                                 
*    Return to caller                                             
     EXEC CICS RETURN END-EXEC.                                   
*                                                                 
 Main-program-exit.                                               
     exit.                                                        
*                                                                 
******************************************************************
 Initial-processing section.                                      
******************************************************************
*                                                                 
*    Obtain the DFHEP.CONTEXT container                           
     EXEC CICS GET CONTAINER('DFHEP.CONTEXT')                     
                   SET(address of EPContext)                      
                   FLENGTH(EPContextLength)                       
     END-EXEC.                                                    
*                                                                 
*    Obtain the DFHEP.DESCRIPTOR container                        
     EXEC CICS GET CONTAINER('DFHEP.DESCRIPTOR')                  
                   SET(address of EPDescriptor)                   
                   FLENGTH(EPDescriptorLength)                    
     END-EXEC.                                                    
*                                                                 
*    Obtain the DFHEP.ADAPTER container                           
     EXEC CICS GET CONTAINER('DFHEP.ADAPTER')                     
                   SET(address of EPAdapter)                      
                   FLENGTH(EPAdapterLength)                       
     END-EXEC.                                                    
*                                                                 
*    Obtain the DFHEP.ADAPTPARM container                           
     EXEC CICS GET CONTAINER('DFHEP.ADAPTPARM')                     
                   SET(address of EPAdaptparm)                      
                   FLENGTH(EPAdaptparmLength)                       
     END-EXEC.                                                    
*                                                                 

*    Check the recoverability of the transport is right for the event
     if not epap-any-recoverable                                  
       perform Check-recoverability.                                

*                                                                 
 Initial-processing-exit.                                         
     exit.                                                        
*                                                                 
******************************************************************
 Process-data-item section.                                       
******************************************************************
*                                                                 
*    Process a data descriptor item                               
*                                                                 
*    Build the data container name: DFHEP.DATA.nnnnn              
     string 'DFHEP.DATA.' delimited by size                       
            ItemNum         delimited by size                     
            into ContainerName                                    
     end-string.                                                  
*                                                                 
*    Obtain the DFHEP.DATA.nnnnn container - if present           
     EXEC CICS GET CONTAINER(ContainerName)                       
                   SET(address of EPData)                         
                   FLENGTH(EPDataLength)                          
                   RESP(Resp) RESP2(Resp2)                        
     END-EXEC.                                                    
******************************************************************
* Any final code to process DATA ITEM to go here                  
******************************************************************
*                                                                 
*    Convert the data according to epde-datatype                  
     perform Convert-data.                                        
*                                                                 
*    Calculate the target field length                            
     move epde-formatlen of epde-item(ItemNum) to TSQFieldLength  
     if TSQFieldLength = 0 and Resp = dfhresp(normal)             
       move TSQItemLength to TSQFieldLength                       
     end-if                                                       
     if 32001 - TSQFieldIndex < TSQFieldLength                    
       compute TSQFieldLength = 32001 - TSQFieldIndex             
     end-if.                                                      
*                                                                 
*    Format the data according to epde-formattype                 
     perform Format-data.                                         
*                                                                 
*    Move over the data item ready for the next one               
     add TSQFieldLength to TSQFieldIndex.                         
*                                                                 
 Process-data-item-exit.                                          
     exit.                                                        
*                                                                 
******************************************************************