分类:
2009-07-08 21:43:10
bankapp是BEA Tuxedo系统提供一个简单的银行应用程序,它完成如下功能:打开和关闭账号,查询账号余额,存款和取款,账号之间转账。
BEA Tuxedo系统提供了一个演示数据库,bankapp例子中有很多个地方使用了命令和SQL代码来访问它。bankapp由如下文件组成:
源文件 |
生成的文件 |
内容说明 |
ACCT.ec |
ACCT.c, ACCT.o, ACCT |
包括两个服务:OPEN_ACCT和CLOSE_ACCT 用于打开和关闭账号 |
ACCTMGR.c |
ACCTMGR |
订阅事件和记录通告日志的服务器,包含: WATCHDOG 和 Q_OPENACCT_LOG 服务 |
AUDITC.c |
AUDITC |
包括一个会话服务器处理来自客户端auditcon的请求 |
BAL.ec |
BAL.c, BAL.o, BAL |
包括一组服务:ABAL, TBAL, ABAL_BID, 和 TBAL_BID 允许audit客户获得银行或支行账号以及余额 |
BALC.ec |
BALC.c, BALC.o, BALC |
包括两个服务:ABALC_BID和TBALC_BID。这些服务和TBAL_BID,ABAL_BID是一样的。 |
bankmgr.c |
bankmgr |
订阅特定事件客客户程序 |
cracl.sh |
- |
用于创建访问控制列表ACL以演示ACL安全的shell脚本 |
crqueue.sh |
- |
notification.用于创建应用程序队列以供事件通告使用的shell脚本 |
crusers.sh |
- |
创建用户和组以演示验证安全级别的shell脚本 |
event.flds |
- |
在事件特征中用到的字段表文件 |
FILES |
- |
bankapp用到的所有文件列表 |
README |
- |
在除NT以外的所有平台上安装指南 |
README.nt |
- |
NT平台上的安装指南 |
README2 |
- |
在bankapp中演示新特性的自述文件 |
README2.nt |
- |
在NT平台上演示新特性自述文件 |
RUNME.cmd |
- |
在NT平台上创建、配置、启动、关闭应用程序的交互式脚本 |
RUNME.sh |
- |
UNIX平台下的脚本文件,功能同上 |
showq.sh! |
- |
显示消息队列的状态和内容的shell脚本 |
TLR.ec |
TLR.c, TLR.o, TLR |
包含三个服务:WITHDRAWAL, DEPOSIT和INQUIRY |
usrevtf.sh |
- |
创建供TMUSREVT服务器使用的ENVFILE文件 |
XFER.c |
XFER.o, XFER |
包括TRANSFER服务 |
aud.v |
aud.V, aud.h |
一个在audit 客户和BAL服务器之间使用的FML view |
appinit.c |
appinit.o |
包含供所有服务器(除TLR以外)使用的用户自定义版的tpsvrinit()和tpsvrdown() |
audit.c |
audit.o, audit |
通过ABAL, TBAL, ABAL_BID和TBAL_BID 服务获得银行及支行账号和余余额的客户程序 |
auditcon.c |
auditcon |
audit的交互式版本,使用ABAL, TBAL, ABALC_BID和TBALC_BID.服务 |
bankapp.mk |
- |
UNIX下应用程序Make文件 |
bankapp.nt |
- |
NT平台下应用程序的Make文件 |
bank.flds |
bank.flds.h |
由服务器使用,包含银行数据库和辅助FML字段文件 |
bank.h |
- |
bankapp应用程序的头文件 |
bankvar |
- |
包括bankapp使用的环境变量,其它环境变量在ENVFILE中定义,后者被前者调用 |
crbank.sh |
crbank |
为bankapp在SHM模式下运行时创建数据的shell脚本 |
crbankdb.sh |
crbankdb |
为一个服务器组创建数据库的shell脚本 |
crtlog.sh |
crtlog, TLOG |
在master站和non-master站的UDL上创建UDL和TLOG的shell脚本 |
driver.sh |
driver |
通过FML缓冲区驱动应用程序的shell脚本 |
envfile.sh |
envfile, ENVFILE |
创建供tmloadcf使用的ENVFILE文件的shell脚本 |
gendata.c |
gendata |
生成10个支行,30个出纳员及200个账号的程序 |
gentran.c |
gentran |
从DEPOSIT, WITHDRAWAL, TRANSFER和INQUIRY.生成事务请求的程序 |
populate.sh |
populate |
通过FML缓冲区向数据库中插入支行、出纳员、和账号信息的shell脚本 |
ubbmp |
TUXCONFIG |
在MP-mode下使用的UBBCONFIG文件 |
ubbshm |
TUXCONFIG |
在SHM-mode下使用的UBBCONFIG文件 |
util.c |
util.o |
包含一组由服务使用的函数,如getstr1()等 |
bankclt.c |
bankclt |
bankapp的客户程序 |
它是一个基于文本的客户,提供了:余额查询、取款、存款、转账、打开账号、关闭、号、退出程序等几大功能。除退出应用程序以外,每一个选项都调用了一个执行如下功能的例程:
⑴.通过get_account(), get_amount(), get_socsec(), get_phone(), get_val()函数从键盘获得用户输入。
⑵.将值存入一个全局的FML缓冲区(*fbfr),有些函数需要更多的字段,需要根据服务器所需的信息来确定。
⑶.通话通过do_tpcall()函数调用BEA Tuxedo系统服务,下面列出了一些函数和服务。
函数名 |
输入FML字段 |
输出 FML字段 |
服务名称 |
BALANCE() |
ACCOUNT_ID |
SBALANCE |
INQUIRY |
WITHDRAWAL() |
ACCOUNT_ID SAMOUNT |
SBALANCE |
WITHDRAWAL |
DEPOSIT() |
ACCOUNT_ID SAMOUNT |
SBALANCE |
DEPOSIT |
TRANSFER() |
ACCOUNT_ID (0) ACCOUNT_ID (1) SAMOUNT |
SBALANCE (0) SBALANCE (1) |
TRANSFER |
OPEN_ACCT() |
LAST_NAME FIRST_NAME MID_INIT SSN ADDRESS PHONE ACCT_TYPE BRANCH_ID SAMOUNT |
ACCOUNT_ID SBALANCE |
OPEN_ACCT |
CLOSE_ACCT() |
ACCOUNT_ID |
SBALANCE |
CLOSE_ACCT |
⑷.调用成功完成后,每个函数可以从返回的FML缓冲区中取得需要的数据
do_tpcall()函数的代码如下:
static int do_tpcall(char *service){
long len;
char *server_status;
/* 开始一个全局事务 */
if (tpbegin(30, 0) == -1) {
(void)fprintf(stderr, "ERROR: tpbegin failed (%s)\n",tpstrerror(tperrno));
return(-1);
}
/* 使用用户数据请求服务 */
if (tpcall(service, (char *)fbfr, 0, (char **)&fbfr, &len,0) == -1) {
if(tperrno== TPESVCFAIL && fbfr != NULL &&
(server_status=Ffind(fbfr,STATLIN,0,0)) != 0) {
(void)fprintf(stderr, "%s returns failure (%s)\n", service,server_status);
}else {
(void)fprintf(stderr,"ERROR: %s failed (%s)\n", service,
tpstrerror(tperrno));
}
/* 终止事务*/
(void) tpabort(0);
return(-1);
}
/* 提交事务 */
if(tpcommit(0) < 0) {
(void)fprintf(stderr, "ERROR: tpcommit failed (%s)\n",tpstrerror(tperrno));
return(-1);
}
return(0);
}
bankapp使用到了Tuxedo系统的ud(1)程序,它允许数据从标准输入读取,并送到服务。populate和driver例程都用到了ud。
在populate中,一个叫gendata的程序把服务请求以及要输入数据库的客户帐号信息一起传给了ud。
在driver中也存在类似的数据流,但程序是gentran,它的作用是把事务传递给应用程序以模拟一个活动系统。
audit中一个请求/响应客户程序,用于支行或全行范围内的余额查询,它用到ABAL、TBAL、ABAL_BID、TBAL_BID服务,你可以通过如下两种方法来激活它:
audit [-a|-t],-a打印全行所有账号总额,[-t]打印全行范围内所有出纳员的现金供应。
audit [-a|-t] branch_ID,打印某支行Branch_ID的上述信息。
audit源代码包括两个主要部分:main()和sum_bal()子程序。两部分都用到了ATMI函数,它用到了一个在aud.h头文件中定义的VIEW类型的缓冲区,如下它的伪码:
main(){
Parse command-line options with getopt();
Join application with tpinit();
Begin global transaction with tpbegin();
If (branch_ID specified) {
Allocate buffer for service requests with tpalloc();
Place branch_ID into the aud structure;
Do tpcall() to "ABAL_BID" or "TBAL_BID";
Print balance for branch_ID;
Free buffer with tpfree();
}else
call subroutine sum_bal();
Commit global transaction with tpcommit();
Leave application with tpterm();
}
sum_bal(){
Allocate buffer for service requests with tpalloc();
For (each of several representative branch_ID’s,one for each site)
Do tpacall() to "ABAL" or "TBAL";
For (each representative branch_ID) {
Do tpgetrply() wtith TPGETANY flag set
to retrieve replies;
Add balance to total;
Print total balance;
}
Free buffer with tpfree();
}
audit.c首先检查命令行参数,看是否指定的支行代号。若指定,则将它放入aud结构,并调用ABAL_BID或TBAL_BID服务来处理请求;否则就调用sum_bal()子过程来处理。它们的程序流程图如下:
auditcon是audit的会话版,它使用了ATMI与会话相关的函数,如使用tpconnect()建立服务与客户之间的连接,用tpsend()发送一条消息,用tprecv()接收消息。如下是它的伪码:
main(){
Join the application
Begin a transaction
Open a connection to conversational service AUDITC
Do until (user says to quit) {
Query user for input
Send service request
Receive response
Print response on user’s terminal
Prompt for further input
}
Commit transaction
Leave the application
}
bankmgr是一个始终运行的应用程序,它订阅应用程序定义的事件,如一次存取超过10000美元的事件。