大型主机应用上的开放系统和中间件 2011年度教育部-IBM精品课程 同济大学软件学院 唐剑锋 billtangjf@gmail.com
第8章 应用CTG实现J2EE应用与CICS的互连
8.1 为什么要使用CTG CICS Transaction Gateway(简称CTG)相比于CICS Web Support的IP直连方式,提供了EIS适配器机制,使得不同平台上的应用可以通过适配器彼此之间进行通信。 适配器可以做不同应用间的数据转换,这就比IP直连的方式提供了更大的灵活性。 适配器的使用可以最大限度地屏蔽掉不同应用之间通讯接口的差异,用户不需要像CICS Web Support那样需要自己来处理通讯间的请求,CWS中用户必须在主机端的应用中加上对协议请求的处理。 应用CTG提供的EIS适配器和JCA架构,用户可以在不对已有系统做任何改动的情况下,实现J2EE应用与CICS应用的互操作。
8.2 CICS Transaction Gateway中的基本组件 CICS Transaction Gateway是一组客户端和服务端的软件,Java应用程序可以通过CTG对远端的CICS应用进行调用。Java应用程序可以是普通的Java应用、Applet、或者是J2EE的应用。 CICS Transaction Gateway主要包含以下组件: 1.Gateway守护程序(Gateway Daemon) Gateway守护程序是CTG中一个长时间运行的进程,它负责在指定的TCP/IP的端口监听Java端的应用(比如J2EE应用)对CTG的请求。CTG支持四种不同的CTG网络协议(TCP,SSL,HTTP和HTTPS)。 2.客户机守护程序(Client Daemon) 客户机守护程序是CTG运行在分布式平台上的组件,它提供了分布式平台上的客户端到CICS服务器的连接。在分布式平台上它支持如下几种方式的连接: (1)APPC连接(SNA)提供了从分布式平台客户端到所有平台上的CICS服务器的连接; (2)TCP62连接(LU6.2/IP)提供了分布式平台客户端到如下平台的CICS服务器的连接:CICS/ESA V4.1、CICS TS V1.2(OS/390)、CICS TS V1.3(OS/390)、CICS TS(z/OS V2); (3)TCP/IP连接提供了分布式平台的客户端到如下CICS服务器的连接:CICS TS(z/OS v2.2)、CICS TS (VSE/ESA V1.1.1)、TXSeries CICS(AIX, Sun Solaris,Windows NT,HP-UX)、CICS TS OS/2。
应用程序使用的 Java 类,被用来调用连结的CICS 服务器上的服务。 3.配置工具 CTG提供了一个配置工具(可以运行在任何分布式平台上)用于对Gateway守护程序和客户端守护程序进行配置,这些配置信息被存放在ctg.ini文件中。下图8-1为配置工具的Java GUI操作界面: 4.Java类库 应用程序使用的 Java 类,被用来调用连结的CICS 服务器上的服务。 图8-1:CTG配置工具界面
8.3 CICS Transaction Gateway接口 CICS Transaction Gateway 主要提供两种编程接口的支持,External Call Interface (ECI)和External Presentation Interface(EPI)。 ECI 提供到基于COMMAREA的CICS程序的调用接口,EPI 则提供了调用基于 3270 的 CICS程序的 API。
8.3.1 External Call Interface ECI接口主要用来调用基于COMMAREA的CICS服务器上的应用程序。 COMMAREA是作为一个缓冲区用来在客户端和CICS服务器之间传递数据。 对于CICS Server来讲ECI客户端的请求调用可以看作是CICS中分布式程序的调用(DPL)。 ECI的调用是现在绝大多数CTG应用所采纳的方式,因为它可以直接访问CICS中应用程序的接口,相对来说实现方式较为简便,便于维护。 本章基于JCA架构的应用实现就是基于ECI的调用实现。 ECI的请求调用主要可以用如下两种Java接口实现: 1.ECIRequest Java Class。它是CTG提供的基础类库,实现了直接通过ECI调用的简单接口,用来调用基于COMMAREA的CICS的应用程序。
2.Common Client Interface(CCI)。它是J2EE Connector Architecture中提供的符合J2EE标准的接口。 CCI中提供了一组标准的Java类,用于J2EE到各种EIS系统的连接,包括CICS。 Java应用程序通过CCI接口同ECI适配器进行通信,由ECI适配器去调用CICS服务器中的应用程序。 JCA中CCI的调用示意图如下图8-2所示:
8.3.2 External Presentation Interface EPI主要用来调用基于3270的Transaction。3270的终端显示层逻辑安装在CICS中(例如MAPSET),EPI的请求使得CICS将此请求视为对终端的操作请求,就像在执行基于MAPSET的CICS应用一样。 由于EPI的请求是基于3270终端的(表现层逻辑),构建起来较为复杂,而且由于EPI是完全基于表现层的调用,如果表现层的逻辑稍加改动,比如说改变一下跳转的页面,或者屏幕的操作方式有些改动,就不得不重新改动Java的代码,维护起来不是十分的方便。 现在通常都是将核心的实现业务流程的程序同表现层分离出来(如果先前它们是混杂在一起的),再通过ECI的方式调用。
EPI请求主要可以采用如下四种Java接口实现: 1.EPIRequest Java类。CTG产品自带的一组Java类的接口,用来调用基于3270的CICS Transaction。由于它是较为底层的接口,现在已经不常使用。 2.EPI支持类。提供调用3270应用的高级接口,它提供了一些模拟3270终端操作的一些类,例如,AID键,MAP中的域数据,屏幕操作,MAP等。调用这些类其实就在模拟3270终端的操作动作,比如按什么键,输入什么数据之类,它会返回3270的响应。由于实现复杂,现在也不经常使用。 3.EPI Bean。基于EPI支持类和Java Bean的开发环境。可以通过可视化的图形界面工具来开发EPI应用。 4.CCI接口。类似ECI中的CCI接口的功能,它同EPI适配器进行通讯,通过EPI适配器同CICS中的3270 Transaction应用进行通信。
8.4 TCP/IP到CICS的连接 8.4.1 TCP/IP在CICS中的定义 针对于ECI,TCPIPSERVICE在CICS中的定义,对比于CWS中TCPIPSERVICE的定义,这里的PROtocol为ECI,Transaction为CIEP,它负责处理ECI的请求。 TCPIPSERVICE的定义如下图8-3所示: 图8-3: ECI TCPIPSERVICE的定义
8.4.2 TCP/IP在CTG中的定义 我们使用CTG配置工具来定义TCP/IP通讯,配置工具会将配置信息存放到ctg.ini文件中。 它主要记录三种信息:Gateway Daemon,Client Daemon和Client Daemon中CICS Server的配置信息。 Gateway daemon的配置信息如下,其中2006为Gateway Daemon监听TCP/IP请求的端口。
Client Daemon的配置信息如下: Client Daemon中CICS Server的配置信息如下,这里指定了Client Daemon连接CICS Server的方式为TCPIP,30084为CICS Server中的TCPIPSERVICE定义的端口。
8.5 应用JCA构建J2EE应用与CICS应用之间的连接 8.5.1 方案一:J2EE连接架构 (JCA)的CCI接口 在最新的CICS Transaction Gateway 中提供了 JCA 的支持,从而允许CICS 久经考验的服务质量可以被 WebSphere Application Server 中运行的 J2EE 应用程序发掘使用。 JCA中应用资源适配器来同EIS系统进行通讯,对于每一种EIS系统都配有特定的资源适配器,例如CICS的ECI资源适配器。 所有的资源适配器提供了如下通用接口: 1.通用的API使得Java组件同适配器进行通讯,这个API被称作Common Client Interface(CCI); 2.一组系统规约,应用服务器可以使用其来管理与资源适配器的交互。
利用CCI接口与JCA资源适配器通讯的示意图如下图8-4所示:
下图8-5给出了利用CCI接口同适配器的交互图,这里需要指定连接信息和交互的数据信息。
8.5.2 方案二:Web服务调用框架 (WSIF) Web服务调用框架(WSIF)提供了一组Java API用来动态地调用Web服务。 JCA中可以用WSDL文件描述ECI资源适配器提供的服务,这里包括用XML描述COMMAREA的数据结构、服务端的地址、服务的操作(请求与响应的消息)。 前端的J2EE应用组件利用WSIF来调用ECI适配器提供的服务,而完全不需要知道CICS中应用程序的数据类型、运行环境等,这对于前端的J2EE应用访问来说是松耦合的。 上面我们讲到了CCI,CCI也是用来同资源适配器进行交互的接口,但是CCI与资源适配器是紧耦合的,也就是说J2EE组件利用CCI同资源适配器进行交互的时候,需要指定适配器所有的相关信息。 例如,适配器所要调用的CICS服务器的地址、端口、CICS的USER ID、Code Page、CICS应用的程序名称、COMMAREA的长度等。 对于一个纯J2EE的应用来说,这些EIS内部接口的信息是不应该暴露出来的,当然我们也可以通过构建一系列的类来封装这些信息,但这终归不是一个好的设计模式。 而JCA中的WSIF架构对CCI的接口加以了封装和改进,使得适配器的接口以WSDL文件的形式暴露给前端的J2EE组件,这样适配器的接口对前端的J2EE应用来说就完全透明了,前端的J2EE可以通过像调用Web Service一样来调用适配器中的接口,这为系统的复用和更新提供了极大的便利。 下面的应用实现部分就是基于WSIF架构。
利用WSIF同适配器进行交互的示意图如下图8-6所示: 下图说明了利用WSIF同资源适配器的交互,Java Service Proxy可以用EJB的Session Bean来实现WSIF的调用,在J2EE端的Servlet中通过调用EJB的Session Bean中的方法就可以实现J2EE应用(WebSphere)同异构平台(CICS)上应用的交互。 利用WSIF同适配器进行交互的示意图如下图8-6所示: 图8-6:利用WSIF同适配器进行交互
WSIF调用方式的伪代码实现如下图8-7所示:
8.6 基于CTG JCA的应用实现 本应用将一个基于COMMAREA的CICS应用,利用CTG中的JCA架构,通过J2EE程序进行访问。 这里我们利用EJB的Session Bean作为WSIF的调用容器,并且为了更好的对Session Bean的访问接口进行封装,利用EJB Access Bean对其进行进一步的封装。 而对于前端的J2EE应用来说只暴露了业务逻辑的访问接口,体现了很好的分层架构思想。 下图8-8为整个应用组件的部署示意图,我们利用Windows平台上的CTG来连接远程的CICS服务器,在WAS服务器中,通过EJB组件通过调用WSIF同CICS ECI适配器进行交互。 图8-8: 应用部署架构图
下图8-9为整个应用的分层架构,这里我们根据CICS中程序的COMMAREA的数据结构生成WSDL,它包含了Web Service调用的所有细节,例如,请求和响应的数据描述、操作方法、服务端的地址绑定等。 利用WSDL构建WSIF组件,通过EJB的Session Bean来调用WSIF,同时为了给前端J2EE访问层组件提供更为良好的接口(屏蔽掉EJB调用时过于繁杂的接口),设置了Access Bean,只暴露给访问层实现业务逻辑调用的接口。 图8-9:应用分层架构图
右方为EJB Session Bean中调用WSIF的核心代码:
以下为在Servlet中通过Access Bean调用Session Bean的代码: