C言語を使用したOracle Tuxedo ATMIアプリケーションのプログラミング

     前  次    新規ウィンドウで目次を開く    PDFとして表示 - 新規ウィンドウ  Adobe Readerを入手 - 新規ウィンドウ
コンテンツはここから始まります

クライアントのコーディング

このトピックには次の項が含まれます:

 


アプリケーションへの参加

ATMIクライアントがサービスをリクエストする場合、Oracle Tuxedo ATMIアプリケーションに明示的または暗黙的に参加している必要があります。アプリケーションに参加すると、クライアントはリクエストを送り、その応答を受け取ることができるようになります。

クライアントが明示的にアプリケーションに参加するには、次のシグネチャを指定してtpinit(3c)関数を呼び出します。

int
tpinit (TPINIT *tpinfo)

クライアントがtpinit()関数を呼び出す前にサービス・リクエスト(またはATMI関数)を呼び出すと、暗黙的にアプリケーションに参加したことになります。その場合、tpinfo引数がNULLに設定されて、tpinit()関数がクライアントではなくOracle Tuxedoシステムによって呼び出されます。tpinfo引数は、タイプがTPINIT、サブタイプがNULLの型付きバッファを指します。TPINIT型バッファはatmi.hヘッダー・ファイルに定義されており、次の情報が格納されています。

char usrname[MAXTIDENT+2]; 
char
cltname[MAXTIDENT+2];
char
passwd[MAXTIDENT+2];
char
grpname[MAXTIDENT+2];
long
flags;
long
datalen;
long
data;

表4-1は、TPINITデータ構造体のフィールドを示しています。

表4-1 TPINITデータ構造体のフィールド
フィールド
説明
usrname
クライアントを表す名前。ブロードキャスト通知と管理統計情報の検索に使用されます。クライアントは、tpinit()関数を呼び出すときにusrnameに値を設定します。この値には、最大文字数がMAXTIDENT (30文字)で、最後がNULLで終わる文字列を指定します。
cltname
アプリケーション定義のセマンティクスに従ったクライアント名。30文字以内で最後がNULLで終わる文字列を指定します。ブロードキャスト通知と管理統計情報の検索に使用されます。クライアントは、tpinit()関数を呼び出すときにcltnameに値を設定します。この値には、最大文字数がMAXTIDENT (30文字)で、最後がNULLで終わる文字列を指定します。

注: sysclientの値は、cltnameフィールド用に予約されています。

passwd
非暗号化形式のアプリケーション・パスワード。ユーザー認証に使用されます。30文字以内の文字列を指定します。
grpname
クライアントをリソース・マネージャ・グループに関連付ける値。これが長さ0の文字列に設定されている場合、クライアントはリソース・マネージャに関連付けられず、デフォルトのクライアント・グループに属します。ワークステーション・クライアントの場合、grpnameの値にはNULL文字列(長さが0の文字列)を指定します。ワークステーション・クライアントの詳細は、『ATMIワークステーション・コンポーネントの使用』を参照してください。
flags
クライアント固有の通知メカニズム、およびシステム・アクセスのモード。この値により、マルチコンテキスト・モードとシングル・コンテキスト・モードが制御されます。フラグの詳細は、「非請求通知の処理」、または『Oracle Tuxedo ATMI C言語関数リファレンス』のtpinit()を参照してください。
datalen
アプリケーション固有データの長さ。TPINIT型バッファのバッファ・タイプ・スイッチ・エントリは、そのバッファに渡される合計サイズに基づいてこのフィールドを設定します。アプリケーション・データのサイズは、合計サイズからTPINIT構造体自体のサイズを差し引き、その値に構造体に定義されているデータ・プレースホルダーのサイズを加算したものです。
data
アプリケーション定義の認証サービスに転送される可変長データ用のプレース・ホルダー。

クライアント・プログラムは、アプリケーションに参加する前にtpalloc()を呼び出してTPINITバッファを割り当てる必要があります。リスト4-1は、TPINITバッファを割り当て、そのバッファを使用してアプリケーション固有の8バイトのデータtpinit()関数に渡す方法を示しています。

リスト4-1 TPINIT型バッファの割当て
.
.
.
TPINIT *tpinfo;
.
.
.
if ((tpinfo = (TPINIT *)tpalloc("TPINIT",(char *)NULL,
      TPINITNEED(8))) == (TPINIT *)NULL){
      Error Routine
}

TPINIT型バッファの詳細は、『Oracle Tuxedo ATMI C言語関数リファレンス』のtpinit()を参照してください。

関連項目

 


TPINIT型バッファの機能の使用

次のTPINIT型バッファの機能をATMIクライアントで利用するには、tpinit()関数を明示的に呼び出す必要があります。

クライアントの名前付け

ATMIクライアントがアプリケーションに参加すると、Oracle Tuxedoシステムによって一意のクライアント識別子が割り当てられます。識別子は、クライアントによって呼び出される各サービスに渡されます。識別子は、非請求通知に使用することもできます。

ユニークなクライアント名とユーザー名をそれぞれ30文字以内で割り当てることもできます。その場合、tpinfoバッファ引数を使用して名前をtpinit()関数に渡します。Oracle Tuxedoシステムでは、各プロセスに関連付けられているクライアント名とユーザー名、およびプロセスが実行されているマシンの論理マシンID (LMID)を組み合せることにより、そのプロセスに対して一意な識別子が使用されます。これらのフィールド値を取得する方法は選択することができます。

注: プロセスがアプリケーションの管理ドメイン以外で実行されている場合(つまり、管理ドメインに接続されたワークステーション上で実行されている場合)、アプリケーションにアクセスするためにワークステーション・クライアントで使用されているマシンのLMIDが割り当てられます。

クライアント・プロセスに対して一意な識別子が作成されると、次の操作を行うことができます。

非請求メッセージの送受信の詳細は、「イベント・ベースのクライアントおよびサーバーのコーディング」を参照してください。tmadmin(1)の詳細は、『Oracle Tuxedo ATMI C言語関数リファレンス』を参照してください。

図4-1は、アプリケーションにアクセスするクライアントに名前を割り当てる方法を示しています。この例では、ジョブ関数を示すcltnameフィールドがアプリケーションで使用されています。

図4-1 クライアントの名前付け

クライアントの名前付け

非請求通知の処理

非請求通知とは、ATMIクライアントが予期していないサービス・リクエストに対するレスポンス(またはエラー・コード)を受け取る通信です。たとえば、管理者が5分後にシステムをシャットダウンすることを通知するメッセージをブロードキャストした場合などです。

クライアントに非請求メッセージを通知する方法は数多くあります。たとえば、オペレーティング・システムがクライアントにシグナルを送って、クライアントの現在の処理を中断させる方法があります。Oracle Tuxedoシステムでは、ATMI関数が呼び出されるたびに非請求メッセージが到着していないかどうかがデフォルトで確認されます。これはディップ・インと呼ばれる方法で、次の利点があります。

ディップ・インでは、メッセージの到着を確認するまでの間隔が長い場合があります。そのため、アプリケーションでtpchkunsol()関数を呼び出して、すでに到着している非請求メッセージがないかどうかを確認できます。tpchkunsol()関数の詳細については、「イベント・ベースのクライアントおよびサーバーのコーディング」を参照してください。

クライアントがtpinit()関数を使用してアプリケーションに参加する場合、フラグを定義して非請求メッセージの処理方法を指定できます。クライアントへの通知では、表4-2に示す値をflagsに指定できます。

表4-2 TPINIT型バッファのクライアント通知でのフラグ
Flag
説明
TPU_SIG
シグナルによる任意通知を選択します。このフラグは、シングル・スレッドでシングル・コンテキストのアプリケーションのみで使用します。このモードの利点は、直ちに通知できることです。このモードには、次のような不都合があります。
  • ネイティブ・クライアントを実行している場合、呼出し側プロセスで送信元プロセスと同じUIDを使用する必要があります。(ワークステーション・クライアントには、この制約はありません。)
  • すべてのプラットフォーム上でTPU_SIGが使用できるわけではありません。特に、MS-DOSワークステーションでは使用できません。
システムや環境の要件を満たしていない場合にこのフラグを指定すると、フラグにTPU_DIPが設定され、ログにイベントが記録されます。
TPU_DIP (デフォルト)
ディップ・インによる任意通知を選択します。クライアントはtpsetunsol()関数を使用してメッセージ処理関数の名前を指定し、tpchkunsol()関数を使用して待機中の非請求メッセージを確認できます。
TPU_THREAD
別のスレッド内のTHREAD通知を指定します。このフラグは、マルチスレッドをサポートするプラットフォーム専用です。マルチスレッドがサポートされていないプラットフォームでTPU_THREADを指定すると、無効な引数として処理されます。その結果、tperrno(5)エラーが返されてTPEINVALが設定されます。
TPU_IGN
任意通知を無視します。

TPINIT型バッファ・フラグの詳細は、『Oracle Tuxedo ATMI C言語関数リファレンス』の「tpinit(3c)」を参照してください。

システム・アクセス・モード

アプリケーションは、protectedまたはfastpathのいずれかのモードでOracle Tuxedoシステムにアクセスできます。ATMIクライアントは、tpinit()関数を使用してアプリケーションに参加するときに、モードをリクエストできます。モードを指定するには、TPINITバッファのflagsフィールドにいずれかのモードを指定して、その値をtpinit()関数に渡します。

表4-3 TPINIT型バッファのシステム・アクセス・フラグ
モード
説明
PROTECTED
アプリケーション内でATMI関数を呼び出し、共用メモリーを使用してOracle Tuxedoシステムの内部表にアクセスします。Oracle Tuxedoシステム・ライブラリ外のアプリケーション・コードからのアクセスに対して、共用メモリーを保護します。この値は、NO_OVERRIDEが指定されている場合を除き、UBBCONFIGの値に優先します。UBBCONFIGの詳細は、『Oracle Tuxedoアプリケーションの設定』を参照してください。
FASTPATH (デフォルト)
アプリケーション・コード内でATMI関数を呼び出し、共用メモリーを使用してOracle Tuxedoシステム内部にアクセスします。Oracle Tuxedoシステム・ライブラリ外のアプリケーション・コードからのアクセスに対して、共用メモリーを保護しません。この値は、NO_OVERRIDEが指定されている場合を除き、UBBCONFIGの値に優先します。UBBCONFIGの詳細は、『Oracle Tuxedoアプリケーションの設定』を参照してください。

リソース・マネージャとの関連付け

アプリケーション管理者は、リソース・マネージャに関連付けられたサーバー(トランザクションを調整するための管理プロセスを提供するサーバーを含む)をグループ化できます。グループの定義については、『Oracle Tuxedoアプリケーションの設定』を参照してください。

アプリケーションに参加している場合、クライアントはTPINIT型バッファのgrpnameフィールドにグループ名を指定して、特定のグループに参加できます。

クライアント認証

Oracle Tuxedoシステムでは、オペレーティング・システムのセキュリティ、アプリケーション・パスワード、ユーザー認証、省略可能なアクセス制御リスト、必須のアクセス制御リスト、リンク・レベルの暗号化などのセキュリティ・レベルを設定できます。セキュリティ・レベル設定の詳細は、『Oracle Tuxedoアプリケーションの設定』を参照してください。

セキュリティ・レベルとしてアプリケーション・パスワードが設定されている場合、アプリケーションに参加するときに、すべてのクライアントがアプリケーション・パスワードを入力する必要があります。管理者はアプリケーション・パスワードを設定したり変更できます。また、そのパスワードを有効なユーザーに提供する必要があります。

このレベルのセキュリティが設定されていると、Oracle Tuxedoシステムで提供されるud()などのクライアント・プログラムでは、アプリケーション・パスワードの入力が求められます。(ud、wud (1)の詳細は、『Oracle Tuxedoアプリケーション実行時の管理』を参照してください。)アプリケーション固有のクライアント・プログラムには、ユーザーからパスワードを取得するコードが記述されていることが必要です。クライアントがアプリケーションに参加するためにtpinit()を呼び出すと、非暗号化パスワードがTPINITバッファに格納されて評価されます。

注: パスワードは画面には表示されません。

tpchkauth(3c)関数を使用すると、次の内容を確認できます。

通常、クライアントはtpinit()より先にtpchkauth()関数を呼び出して、初期化時に指定する必要のあるセキュリティ情報を確認します。

セキュリティのプログラミング手法の詳細は、『Oracle CORBAアプリケーションにおけるセキュリティの使用』を参照してください。

 


アプリケーションからの分離

ATMIクライアントがすべてのサービスをリクエストして、それに対する応答を受信したら、tpterm(3c)関数を使用してアプリケーションから分離できます。tpterm()関数には引数がなく、エラー時には– 1を返します。

 


クライアントのビルド

実行可能ATMIクライアントをビルドするには、buildclient(1)コマンドを実行して、Oracle Tuxedoシステム・ライブラリとその他のすべての参照ファイルを使用してアプリケーションをコンパイルします。次は、buildclientコマンドの構文です。

buildclient filename.c -o filename -f filenames -l filenames

表4-4は、buildclientコマンドのオプションを示しています。

表4-4 buildclientのオプション
オプションまたは引数
説明
filename.c
コンパイルするC言語のアプリケーション。
-o filename
実行可能な出力ファイル。出力ファイルのデフォルト名はa.outです。
-f filenames
Oracle Tuxedoシステムのライブラリより先にリンクされるファイルのリスト。-fオプションは、コマンド行で複数回指定したり、各-fに複数のファイル名を指定できます。Cプログラム・ファイル(file.c)を指定すると、リンクされる前にコンパイルが行われます。他のオブジェクト・ファイル(file.o)を個別に指定したり、アーカイブ・ファイル(file.a)にまとめて指定することもできます。
-l filenames
Oracle Tuxedoシステム・ライブラリの後にリンクされるファイルのリスト。-lオプションは、コマンド行で複数回指定したり、各-lに複数のファイル名を指定できます。Cプログラム・ファイル(file.c)を指定すると、リンクされる前にコンパイルが行われます。他のオブジェクト・ファイル(file.o)を個別に指定したり、アーカイブ・ファイル(file.a)にまとめて指定することもできます。
-r
実行可能サーバーにリンクされるリソース・マネージャのアクセス・ライブラリ。アプリケーション管理者は、buildtms(1)コマンドを使用して、すべての有効なリソース・マネージャ情報を$TUXDIR/updataobj/RMファイルに事前に定義しておく必要があります。指定できるリソース・マネージャは1つだけです。詳細は、『Oracle Tuxedoアプリケーションの設定』を参照してください。

注: Oracle Tuxedoライブラリは自動的にリンクされます。コマンド行にOracle Tuxedoライブラリを指定する必要はありません。
注: リンクの編集はbuildclientコマンドを実行して行う必要があります。

リンクするライブラリ・ファイルの指定順序は重要です。関数を呼び出す順序と、それらの関数への参照を含むライブラリによって、この順序が決定されます。

デフォルトでは、buildclientコマンドはUNIXのccコマンドを呼び出します。環境変数CCを指定して別のコンパイル・コマンドを指定したり、CFLAGSを指定してコンパイル・フェーズやリンク・フェーズにフラグを設定することができます。詳細は、「環境変数の設定」を参照してください。

buildclient -C -o audit -f audit.o

次のコマンド行の例では、Cプログラムaudit.cをコンパイルして、実行可能ファイルauditを生成しています。

buildclient – o audit – f audit.c

関連項目

 


クライアント・プロセスの例

リスト4-2に示す次の擬似コードは、通常のATMIクライアント・プロセスがアプリケーションに参加してから分離するまでの処理を示しています。

リスト4-2 クライアント・プロセスのパラダイム
main()
{
      check level of security
      call tpsetunsol() to name your handler for TPU_DIP
      get usrname, cltname
      prompt for application password
      allocate a TPINIT buffer
      place values into TPINIT buffer structure members

      if (tpinit((TPINIT *) tpinfo) == -1){
            error routine;
      }

      allocate a message buffer
      while user input exists {
            place user input in the buffer
            make a service call
            receive the reply
            check for unsolicited messages
      }
      free buffers
      . . .
      if (tpterm() == -1){
            error routine;
      }
}

エラーが発生すると-1が返され、アプリケーションが外部グローバル変数tperrnoにエラーの原因を示す値を設定します。tperrnoは、atmi.hヘッダー・ファイルに定義されています。詳細については、『ファイル形式、データ記述、MIBおよびシステム・プロセス・リファレンス』tperrno(5)を参照してください。通常、プログラマが発生したエラーの種類を示すエラー・コードをこのグローバル変数に設定します。tperrnoの値については、「システム・エラー」を参照してください。各ATMI呼出しで返される全エラー・コードのリストについては、『Oracle Tuxedo ATMI C言語関数リファレンス』C言語アプリケーション・トランザクション・モニター・インタフェースに関する項を参照してください。

リスト4-3は、tpinit()tpterm()関数の使用方法を示しています。これは、Oracle Tuxedoシステムに提供されている銀行業務のサンプル・アプリケーションbankappから引用したものです。

リスト4-3 アプリケーションへの参加と分離
#include <stdio.h>         /* UNIX */
#include <string.h> /* UNIX */
#include <fml.h> /* BEA Tuxedo System */
#include <atmi.h> /* BEA Tuxedo System */
#include <Uunix.h> /* BEA Tuxedo System */
#include <userlog.h> /* BEA Tuxedo System */
#include "bank.h" /* BANKING #defines */
#include "aud.h" /* BANKING view defines */

...

main(argc, argv)
int argc;
char *argv[];

{
      ...
      if (strrchr(argv[0],'/') != NULL)
       proc_name = strrchr(argv[0],'/')+1;
      else
       proc_name = argv[0];
      ...
      /* Join application */
      if (tpinit((TPINIT *) NULL) == -1) {
       (void)userlog("%s: failed to join application\n", proc_name);
         exit(1);
      }
      ...
      /* Leave application */
      if (tpterm() == -1) {
       (void)userlog("%s: failed to leave application\n", proc_name);
        exit(1);
      }
}

この例は、tpinit()を呼び出すことによって、アプリケーションに参加しているクライアント・プロセスを示しています。エラー(戻り値が– 1)が発生すると、このプロセスはCプログラム文のprintf()と似た引数を取るuserlog()を呼び出して、中央イベント・ログにメッセージを書き込みます。詳細は、『Oracle Tuxedo ATMI C言語関数リファレンス』の「userlog(3c)」を参照してください。

同様に、tpterm()を呼び出し、エラーが発生すると、このプロセスは中央イベント・ログにメッセージを書き込みます。


  先頭に戻る       前  次