Tivoli Service Desk 6.0 Developer's Toolkit Interface Designer の手引き

第 7 章: CPIC の使用法

目次に戻る


概要

概説

通信用共通プログラミング・インターフェース (CPIC) は、アプリケーション間通信に必要となるアプリケーション用の一貫した API を提供します。CPIC インターフェースは SNA の LU 6.2 を使用して、1 セットのアプリケーション相互間サービスを作成し、これには次が含まれます。

これらのサービスを TSD Script プログラマーに対して拡張するために、CPIC コマンドが TSD Script 言語内にビルドされています。各プラットフォーム間で一貫性を確保するために、基本 APPCマクロを介して CPIC が選択されています。

本書のこの項では、TP をビルドするための CPIC の使用法を TSD Script プログラマーに説明します。 SAA CPIC プログラミングの詳細については、IBM 資料の CPI コミュニケーション・インターフェース解説書 (SC88-7217) を参照してください。

CPIC は、作業するすべての CPIC コマンドにインストールする必要があります。CPIC が適切にインストールされていない場合には、 CPIC コマンドを使用すると、Tivoli Service Desk (TSD) Developer's Toolkit によってエラー・メッセージが表示されて、その CPIC をロードできなかったことが示されます。

用語 & 概念

APPC

APPC は拡張対等通信です。

基本会話

基本会話とは、アプリケーションが標準バイト・ストリーム形式でデータを交換する会話タイプです。この形式では (LL と呼ばれる) 2 バイト長のフィールドが含まれていて、後に続くバッファーの長さを指定します。LL データの各グループは 論理レコードと呼ばれます。

会話

会話とは、データを交換するために CPIC または APPC を使用する 2 つのアプリケーション間の論理結合のことです。この会話には、 マップ式基本の 2 つのタイプがあります。会話では、セッションを使用してアプリケーション間が接続されます。CPIC アプリケーションは、他の CPIC アプリケーションと会話するのと同じ方法で APPC アプリケーションと会話することができます。

DDF

DDF (データ記述ファイル) とは、TSD Script レコード構造と送信されたバイト・バッファー間の関係をマップするために使用されるファイルです。

LU

LU (論理装置) は実際的には 1 つの仮想計算機です。それぞれの物理マシンを LU として指定できると同時に、複数の LU を 1 つの物理マシン上に構成することもできます。CPIC は LU タイプ 6.2 のノードだけを使用することに注意してください。

マップ式会話

マップ式会話とは、パートナー間で事前定義形式の任意のデータ・レコードを交換できる会話タイプのことです。

モード名

モード名は、会話中に LU 間のセッションのプロパティーを指定するために APPC で使用されます。これらのプロパティーには、サービス・クラスが含まれています。

ノード・サービス

ノード・サービスは、LU の基本ユーティリティー機能を提供する 1 つまたはセットのアプリケーションです。提供されるサービスには、サイド情報の操作、アプリケーション開始処理、およびアプリケーション終了処理が含まれます。OS/2 のノード・サービスは Communications Manager (CM) または Communications Manager/2 (CM/2) によって提供されます。

パートナー

パートナーは、CPIC 会話を介してデータを交換する 2 つの CPIC アプリケーションです。

CPIC 会話は 全二重にすることができます。これは、CPIC 会話中のある特定の時点で、片方のパートナーが送信の許可を得て、もう一方のパートナーが受信状態になる (これがデータ受信可能になる) ことを意味します。受信状態のアプリケーションは、データの送信が必要な時に送信要求を出すことができます。 パートナーにはこの要求が通知されて、要求元のアプリケーションは StatusReceived パラメーターに通知を受信します。

SDN

SDN (記号宛先名) は Communications Manager/2 の CPIC 構成名であり、これによってアプリケーションは会話割り振り要求で使用するセットの属性を指示することができます。

セッション

セッションとは、2 つの LU 間の論理結合です。LU はこのセッションを介して通信します。

サイド情報

会話を確立しようとする時に CPIC で使用される初期化情報です。 サイド情報にはパートナー LU 名、モード名、および TP 名が含まれています。この情報は会話の前に構成されます。

注: サイド情報は SDN によって参照されます。

SNA ネットワーク

SNA ネットワークは LU の論理ネットワークです。

同期レベル

同期レベルは、CPIC 会話が使用する同期のレベルを示します。同期レベルは次の 1 つにすることができます。

SYNC_POINT

SYNC_POINT は、ユーザー・アプリケーションが完全な SAA リソース回復操作、すなわち、 「Take Commit」および「Take Backout」通知をサポートしていることを示します。

注: SYNC_POINT は OS/2 ではサポートされていません。

TP

TP (トランザクション・プログラム) は、会話に参加するために CPIC または APPC コマンドを使用するアプリケーションです。

TP 名

TP 名はトランザクション・アプリケーションの名前です。この名前はサイド情報に指定されます。オペレーティング・システムによっては、TP 名はターゲット LU のノード・サービス・アプリケーションのテーブル項目を指定することがあります。このテーブルは、TP の開始に必要な情報の検索で使用されます。

他のプログラムとの会話の開始

単純な会話の例

アプリケーションが他のプログラムとの会話を開始する時に使用する簡単な例は次の通りです。

  1. プログラム A は CPICInitialize コマンドを出して、会話の開始を準備します。これは、 プログラム C を会話のターゲットとして指定するための SDN を提供します。 プログラム A はその会話の固有 ID を受信します。
  2. プログラム A はその会話 ID を使用して CPICAllocate コマンドを出します。
  3. ノード・サービスを介して、新規の会話の受け入れのためにプログラム C を開始する必要があることを CPIC はパートナー LU (ステップ 1 で使用したサイド情報に指定される) に知らせます。
    結果: プログラム C が開始されて CPICAccept コマンドを出します。これは、会話中で交換され、その後の CPIC コマンドで使用する会話 ID を受信します。

TSD Script データ記述ファイル

概説

TSD Script では、メモリー構造の割り振りサイズを直接制御することはできません。

これは、第 4 世代言語の有用な属性とみなされますが、CPIC アプリケーションの作業では困難な局面を提示することもあります。 CPIC アプリケーションは特定のサイズおよび形式のバイト・バッファーを送信し受信します。パートナー・アプリケーションはローカル・アプリケーションとは異なった形式の記憶域を使用することができ、これには非 Intel 整数および EBCDIC 文字ストリングも含まれます。

データ記述ファイル (または DDF) は異なったバッファー・サイズの可能性をアドレスします。 DDF は送信されるバイト・バッファーのフォームを定義して、フォーマット変換 / 会話を指定します。 TSD Developer's Toolkit はこれらの DDF を、CPIC アプリケーションとの発信と着信の両方のバッファーで "フィルター" として使用します。

DDF の基本構造は次の通りです。

-- ダブル・ダッシュは行の終わりに対するコメントです。
-- 最初のセクションはパートナー・セクションです。
*PARTNER
-- 文字変換タイプ
EBCDIC=TRUE
-- 整数バイト順序
NON_INTEL=TRUE
-- 文字変換テーブル。指定しないと、TSD Developer's Toolkit は
-- CM/2 AE テーブルを使用します。このデフォルト・テーブルは、
-- ユーザーの使用に不十分な場合があります (たとえば、組み込み
-- スペースを x'00') に変換します。より一般的な変換テーブルが
-- 必要な場合には、CM/2 変換テーブル・ファイル名を ACSGTAB.DAT
-- に設定します。これは CM/2 によって提供されます。その後で、
-- CUSTOM_CONVERT を TRUE に設定します。
CUSTOM_CONVERT=TRUE
-- このセクションはフィールド・セクションです。これを使用して、
-- レコードの各フィールドとそのバイト・マッピングおよび変換を
-- 記述します。このセクションは本質的に、受信直後 (変換前)
-- または送信直後 (変換後) にデータ・バッファーをどのように
-- 表示することができるかを示します。
*FIELDS
-- Fieldname Type ByteWidth SendUnknowns? Default
   name CHAR 20 FALSE
   street CHAR 20 TRUE
   age INTEGER 20 TRUE
   birthDate CCYYMMDD 8 FALSE

この例では、パートナー・アプリケーションは非 Intel スタイルの整数 (IBM システム 370 など) の EBCDIC マシン上で実行されます。送信されるレコードは次のように TSD Script に宣言されます。

SomeRecordName IS RECORD
   name :STRING;
   street :STRING;
   age :INTEGER;
   birthDate :DATE;
   description:STRING;
      END;

記述フィールドは DDF に組み込まれません。これは、記述フィールド は CPIC 通信中に転送されないことを表します。

パートナー・セクション

DDF のこのセクションでは、パートナー・アプリケーションのマシン・タイプについて説明します。このセクションの始めには、テキスト *PARTNER のマークがあります。パートナー・セクションは、TSD Developer's Toolkit が実行するデータ変換のタイプを示します。たとえば、EBCDIC=TRUE の設定では、パートナー・アプリケーションとの通信時にすべての文字ストリングを EBCDIC に (あるいは EBCDIC から) 変換することを示します。

パートナー属性

パートナー・セクションでは、次の属性を設定しなければなりません。設定されない属性では、指示されてデフォルト値がとられます。

フィールド・セクション

この DDF セクションは、CPIC データ・バッファーでパックまたはアンパックされるフィールドおよびフィールド・タイプを指定します。DDF のこのセクションは "*FIELDS" を含む行で開始します。 フィールド・セクションの各行は 1 つの TSD Script 転送済みレコード・フィールドに適用されます。このような行の形式は次の通りです。

{fieldname} {fieldtype} {bytewidth} {sendunknowns?} {default}

空白文字がそれぞれの列を分割しています。列定義は次の通りです。

$INCLUDE コマンド

$INCLUDE コマンドは DDF の編成を単純化します。 このコマンドは、 他のファイルを動的に "リンク" する機能を提供します。 TSD Developer's Toolkit が $INCLUDE コマンドを検出すると、指定された DDF をロードして、そのフィールド定義を現行の DDF に配置します。

$INCLUDE コマンドは、フィールド・セクションの任意の位置に組み込むことができます。 $INCLUDE コマンドの形式は次の通りです。

$INCLUDE({DDFname})

ファイルが現行ディレクトリー中にない場合には、TSD Developer's Toolkit はファイルで DPATHを検索します。これが見つからない場合には、TSD Developer's Toolkit がエラーを戻します。

$SIZEOF コマンド

$SIZEOF コマンドは組み込みファイルのサイズを再計算しますので、別のフィールドが追加された場合に、組み込みファイルを手動で再カウントする必要はありません。

$SIZEOF および $INCLUDE コマンドは、ベクトル化バッファーの設定なと、特別な場合に使用されます。これらは、次の通り組み合わせで使用することができます。

*PARTNER
   EBCDIC =TRUE
   NON_INTEL =TRUE
   CUSTOM_CONVERT =TRUE
*FIELDS
GDS1310 INT 2 TRUE 4880
GDS1311LEN INT 2 TRUE
   $SIZEOF(1311.DDF) + 2 $INCLUDE(1311.DDF)
GDS1549LEN INT 2 TRUE
   $SIZEOF(1549.DDF) + 2 $INCLUDE(1549.DDF)
DataLen INT 2 TRUE
   $SIZEOF(RTRNDATA.DDF) + 2 $INCLUDE(RTRNDATA.DDF)

DDF フィールド・タイプ

DDF 処理で認識されるタイプは次の通りです。

Communications Manager/2 での CPIC の使用法

概説

OS/2 CPIC アプリケーションの作成を試みる前に、知っておく必要があるいくつかの詳細事項があります。これらの一部は、ユーザー・システム上にあるノード・サービスのタイプによってグループに分けることができます。

着信割り振り

ノード・サービスが TP を設定して着信割り振りを受信するという方法のために、OS/2 CPIC アプリケーションを SNA サービス TP にすることはできません。着信割り振りの操作方法を要約した次のステップを検討してください。

  1. ノード・サービスが処理を開始して、APPCTPN の名前の環境変数を TP 名と等しく設定します。
  2. アプリケーションが Accept コマンドを出すと、ノード・サービスは受諾アプリケーション環境の APPCTPN をチェックします。
  3. ノード・サービスは同じ TP 名をもつものについて、待機着信割り振りのリストをスキャンします。
  4. その名前が見つかった場合には、ノード・サービスはその呼び出しを完了します。SNA サービス TP 名は 16 進数で開始するので、これを OS/2 環境変数に設定することはできません。

TP との複数の TSD Script アプリケーション

TP をセットアップしたい TSD Script アプリケーションが複数ある場合には、特別なセットアップを行なう必要があります。 Communications Manager/2 では、1 つの TP 定義の OS/2 アプリケーション PATH およびファイルとして指定できるのは kml.exe だけです。他のものでは、次のコマンドを含む OS/2 コマンド・ファイルを作成します。

SET APPCTPN={your TP name}
START /C KML /U{path to your KB} {your KB name}
EXIT

Communications Manager/2 バージョン 1.1 (CM/2)

Communications Manager/2 では、複数の会話を受け入れる単一 CPIC プロセスを使用することができます。 さらに、CPIC アプリケーションは、その前に Accept コマンドが出されていないかぎり、1 つの Initialize コマンドを出すことができます。

TSD Script CPIC 事例研究

概説

この項には、簡単な CPIC アプリケーションを作成するプロセスの簡単な事例研究が示されています。アプリケーションを設計して、ファイル転送を完了します。

CPIC の利点を図示するために、この事例研究には 2 つのモジュールがあります。 最初の例のモジュールでは、アプリケーションが作成されます。 2 番目の例のモジュールでは、パフォーマンスを向上させるために、そのアプリケーションにいくつかの小変更を行ないます。

前提事項

この事例研究では、CPIC、Communications Manager/2、および一般的な通信処理に慣れている、という幾つかの前提事項があります。たとえば、Communications Manager/2 CMSETUP ユーティリティーの使用に慣れているものと仮定されています。

パートナー・アプリケーション (RCV.CMD)

開始するには、REXX で作成されたパートナー・アプリケーションを検討してください。

REXX パートナー・アプリケーションは RCV.CMD の名前が付けられます。本質的に、アプリケーションが現在データを送信していないことを受信状況パラメーターが指示するまで、このアプリケーションはデータを送信 (それを語幹変数に保管) します。

次のコードの例は、このアプリケーションに関する追加記述を提供するための説明です。

/* RCV.CMD */ 
/* Receives data strings, building a buffer of all data. /*Upon completion of*/
/* receiving, sends back the buffer. */ 
/* CPIC commands used: CMACCP */ 
/*                     CMCFMD */ 
/*                     CMDEAL */ 
/*                     CMRCV */ 
/*                     CMSEND */ 
/* a few useful constants */ 
CM_OK               = 0 
/* status received */ 
CM_SEND_RECEIVED    = 1 
CM_CONFIRM_RECEIVED = 2 
/* data received */ 
CM_NO_DATA_RECEIVED = 0
MaxLength           = 257; 
BufferLen           = 0; 
FileBuffer.0        = 0; 
'CPICREXX' 
address cpicomm 
'CMACCP Conv_ID RetC'; 
if \(RetC = CM_OK) then do 
     SAY 'ACCP = 'Retc 
   end; 
   'CMRCV Conv_ID Data MaxLength DataReceived 
    ReceivedLength StatusRecvd ReqToSendRecvd Retc'; 
if \(RetC = CM_OK) then do 
      SAY 'RCV = 'Retc 
   end; 
do while (RetC = CM_OK) & 
  (StatusRecvd \= CM_SEND_RECEIVED) 
  if (DataReceived \= CM_NO_DATA_RECEIVED) then do 
/*    SAY Data */ 
      FileBuffer.0 = FileBuffer.0 + 1; 
      i = FileBuffer.0; 
      FileBuffer.i = Data; 
   end; 
   if (StatusRecvd = CM_CONFIRM_RECEIVED) then do 
      'CMCFMD Conv_ID RetC'; 
   end; 
   'CMRCV Conv_ID Data MaxLength DataReceived 
    ReceivedLength StatusRecvd ReqToSendRecvd Retc'; 
   if (RetC \= CM_OK) then do 
      SAY 'RCV = 'Retc 
end; 
   end; 
SAY 'Re-transmitting file' 
DO i = 1 TO FileBuffer.0 
   BufferLen = LENGTH(FileBuffer.i); 
   Data = FileBuffer.i; 
   'CMSEND Conv_ID Data BufferLen ReqToSendRecvd RetC'; 
   if (RetC \= CM_OK) then do 
      SAY 'SND = 'Retc 
   end; 
      END; 
'CMDEAL Conv_ID RetC'; 
address cmd 
'EXIT'

例題モジュール 1 - FILESND.KB

このアプリケーションのゴールは、テキスト・ファイルを読み取って、各行をパートナー・アプリケーションに送信することです。アプリケーションがファイル転送を完了した後、同じファイルの受信バックを再開して、表示ウィンドウに各行を表示します。

  1. コマンド KP FILESND によってファイルを解析します。
  2. CM/2 フォルダーから CMSETUP アプリケーションを開始します。
    結果:「CPI コミュニケーション・マネージャー構成ユーティリティー」ダイアログ・ボックスが表示されます。
  3. そのボックスに名前 FILESND を入力します。
  4. CPI 通信メニューから、「SNA 機能」を選択します。
    結果:「CM/2 構成定義」ダイアログ・ボックスが表示されます。
  5. サイド情報項目を設定します。
  6. 「SNA 機能」ダイアログ・ボックスでは、「CPI 通信サイド情報」アイテムを選択します。
  7. 「作成」を選択します。
  8. このダイアログ・ボックスには、次の通り入力してください。
    SDN = FILESND
    Target LU = {target machine name here}
    TP Name = FILERCV
    Security = NONE
    Mode = #INTER
  9. 「了解」を選択します。
  10. 「トランザクション・プログラム定義」アイテムを選択します。
  11. 「作成」を選択します。
  12. このダイアログ・ボックスに次の値を入力します。
    Service TP = deselected
    TP Name = FILERCV
    OS/2 Program PATH and Filename = CMD.EXE
    Conversation security required = deselected
    Program Parameters = /C {PATH to tutorial code}RCV.CMD
  13. 「続行」を選択します。
  14. 次の通り入力します。
    Presentation Type = Background
    Operation Type = Queued, Attach Manager started

セットアップ手順の検討

ステップ 3 から開始して、Communication Manager/2 のサイド情報テーブルに項目を設定します。サイド情報テーブルは会話の初期化の時に使用されます。初期化では、次の通り行われます。

  1. アプリケーションは CPICInitialize を呼び出して、SDN をパラメーターとして渡します。 SDN はサイド情報テーブルに対するキーとして機能します。
  2. CPIC は SDN を使用して、新規会話の属性を設定します。この属性はターゲット・マシンおよび TP を表記することができます。

このメソッドを使用して、ハード・コーディングのサイト固有情報なしで CPIC アプリケーションを作成することができます。また、これによって、このタイプの情報にアクセスするための CPIC アプリケーションのすべての標準メソッドも提供されます。

ステップ 8 から開始して、TP 定義を作成します。この項目は、特定の TP の開始方法をノード・サービスに通知します。

会話が割り振られると、その割り振りを要求した LU は、ターゲット LU ノード・サービス・システムに必要な TP 名を送信します。ノード・サービス・システムは、その TP 名がシステムに定義されているかどうかを調べるためにチェックします。それが定義されている場合には、ノード・サービスは TP の開始方法の指示に従います。アプリケーションを正常に開始できる場合には、(TP で開始される Attach Manager が設定される時) それを行ないます。その後、TP は CPICAcceptを出します。 要求元 LU が成功指示を受け取ると、会話が開始されます。

この REXX アプリケーションでは、OS/2 コマンド・プロセッサーが開始されます (CMD.EXE)。パラメーター・ストリングは、コマンドの完了 (/C) 時に終了するための CMD.EXE、およびどのコマンドを実行する (RCV.CMD) かを通知します。

コマンド行からの RCV.CMD ファイルの開始

この事例研究の次の部分は、OS/2 コマンド行から RCV.CMD ファイルを開始します。

  1. どの TP が着信会話を待機しているかを CM/2 に通知するための標識を設定します。これは、コマンド・セッションに環境変数を設定することによって行なわれます。

    SET APPCTPN=FILERCV

    (任意指定) 着信割り振りの初期待機を回避するには、CMLIB ディレクトリーのノード定義ファイル (NDF) を編集することができます。このファイルには、Communications Manager/2 構成ファイルと同じ名前があります。
  2. FILERCV TP の属性の定義セクションを調べます (FILERCV の検索)。
  3. INCOMING_ALLOCATE_TIMEOUT および RECEIVE_ALLOCATE_TIMEOUT を正整数に変更します (単位は秒数で、それぞれ 180 が良好なベンチマークです)。
  4. そのファイルを保管します。
  5. これらの変更を有効にするには、「CM セットアップ・ユーティリティー」を開始し、データ・フィールドに対して変更を行 ない、CM セットアップによって再検査が行なわれ、その変更が動的に適用されるようにします。
  6. RCV を入力し ENTER を押すことによって、REXX アプリケーションを実行します。
    結果: アプリケーションは、割り振りが到着するか、あるいは RECEIVE_ALLOCATE_TIMEOUT のタイムアウトを 超えるまで休止します。完了時には、このアプリケーションは現行のコマンド処理を終了します。
    注: FILESND.KB の開始が可能になるまで、REXX アプリケーションは開始しないでください。

FILESND.KB の実行

これによって、2 つのアプリケーション間でソース・ファイルを相互に受け渡しして、その結果をウィンドウに表示します。

ダブル転送では、完了までしばらく時間がかかることがあります。ウィンドウのファイル・リストの下に、時間の結果が示されます。

さらに、ファイルの各行の行番号も示されます。これらの番号はテキスト・ファイルの各行とともに受け渡しされます。

FILESND.KB 行リスト

次の番号付き行のこのセクションは、ファイルに関する記述です。

1
2      KNOWLEDGEBASE FILESND;
3
4      ROUTINES 
5      PROCEDURE DoConversation(VAL Args:List of String);
6                              (* sdn, infile *) 
7
8
9      PRIVATE 
10
11     CONSTANTS 
12        CPIC_SUCCESS IS 1; 
13
14     TYPES 
15        FileRec IS RECORD 
16           LineNbr:Integer; 
17           Buff:String; 
18        END; 
19
20     ROUTINES 
21
22     FUNCTION RcvData(REF w:WINDOW, VAL 
                        Conv:Conversation) 
                        :INTEGER IS 
23     VARIABLES 
24        totalBuff :FileRec; 
25        dataRcvd  :integer; 
26        statRcvd  :integer; 
27        reqTSRcvd :integer; 
28        rc        :integer; 
29     ACTIONS 
30        IF (not(Known(w))) THEN 
31        WinCreateScrollWindow($DESKTOP,w, 
32                              $NullHandler, 
                                1,1,67,7, 
                                'FileSnd','', 0, 
                                  $WinBorder+ 
                                  $WinTitle+ 
                                  $WinHScroll+ 
                                  $WinVScroll+ 
                                $WinSysMenu+ 
                                  $WinResize); 
      END; 
33       REPEAT 
34       rc := CPICReceive(Conv,'FILEREC.DDF', 
                              totalBuff,DataRcvd, 
                              StatRcvd,ReqTSRcvd); 
35          IF (rc > 0) THEN 
36          IF ((StatRcvd = $CPICConfirmReceived) or 
37             (StatRcvd = $CPICConfirmSend 
                Received)) THEN 
38              rc := CPICConfirmed(Conv); 
39       END; 
40            totalBuff.buff := StrTrim 
                (totalBuff.buff); 
41             WinWriteLn(w,totalBuff.lineNbr:5&' 
                         :'&totalBuff.buff); 
42        END; 
43       UNTIL ((rc <> 1) OR ((StatRcvd = 
                         $CPICSendReceived) OR 
44                  (StatRcvd = $CPICConfirmSend 
                     Received))); 
45       Exit(rc); 
46    END; -- RcvData
47
48
49 --------------------------------------------- 
50 -- 説明: 指定されたファイルに読み込み、
      指定された SDN を介して指定された
51 -- パートナーに、各行を cpic 経由で
      送信します。
52 --------------------------------------------- 
53 PROCEDURE DoConversation(VAL Args:List of 
                            String) IS 
54 VARIABLES 
55    Conv     :Conversation; 
56    fRec     :FileRec; 
57    ReqTSRcvd:INTEGER; 
58    rc       :INTEGER; 
59    inf      :FILE; 
60    w        :WINDOW; 
61    t1,t2    :TIME; 
62 ACTIONS 
63    t1       := $NOW; 
64    IF (ListLength(Args) <2) THEN WinMessageBox($DESKTOP,?ops? $MBOK,?ML FILESND {SDN} {INFILE}?; Exit; END; FOpen(inf,Args[2],$Read); rc :="CPICInitialize(Conv,Args[1]);" IF (rc <CPIC_SUCCESS) THEN WinMessageBox($DESKTOP, ?PIC Error?$MBOK, ?nit returns ?rc); Exit; END; rc :="CPICSetSyncLevel(Conv," $CPICNone); IF (rc <CPIC_SUCCESS) THEN WinMessageBox($DESKTOP,?PIC Error?$MBOK, ?SL returns ?rc); END; rc :="CPICAllocate(Conv);" IF (rc < CPIC_SUCCESS) THEN WinMessageBox($DESKTOP, ?PIC Error?$MBOK, ?llc returns ?rc); Exit; END; rc :="CPICSetPrepareToReceiveType" (Conv, $CPICPrepToReceiveFlush); IF (rc < CPIC_SUCCESS) THEN WinMessageBox($DESKTOP, ?PIC Error?$MBOK, ?PTR returns ?rc); END; fRec.lineNbr :="0;" while (FReadLn(inf,fRec.Buff)> <2) THEN
65    WinMessageBox($DESKTOP,'Oops',
                    $MBOK,'KML FILESND {SDN}
                   {INFILE}');
66       Exit;
67    END;
68
69    FOpen(inf,Args[2],$Read);
70
71    rc := CPICInitialize(Conv,Args[1]);
72    IF (rc < CPIC_SUCCESS) THEN
73       WinMessageBox($DESKTOP,
                        'CPIC Error',$MBOK,
                      'Init returns '&rc);
74       Exit;
75    END;
76    rc := CPICSetSyncLevel(Conv, $CPICNone);
77    IF (rc < CPIC_SUCCESS) THEN
78       WinMessageBox($DESKTOP,
                        'CPIC Error',$MBOK,
                      'SSL returns '&rc);
79    END;
80    rc := CPICAllocate(Conv);
81    IF (rc < CPIC_SUCCESS) THEN
82       WinMessageBox($DESKTOP,
                        'CPIC Error',$MBOK,
                      'Allc returns '&rc);
83       Exit;
84    END; 
85
86    rc := CPICSetPrepareToReceiveType
               (Conv, $CPICPrepToReceiveFlush); 
87    IF (rc < CPIC_SUCCESS) THEN
88       WinMessageBox($DESKTOP,
                        'CPIC Error',$MBOK,
                      'SPTR returns '&rc);
89    END;
90
91    fRec.lineNbr := 0;
92    while (FReadLn(inf,fRec.Buff) > 0) do
93         fRec.Buff := fRec.Buff & Char(13) & 
                           Char(10);
             -- add CR LF
94      fRec.lineNbr := fRec.lineNbr + 1;
95      rc := CPICSend(Conv,
                           'FILEREC.DDF',
                           fRec,
                           ReqTSRcvd);
96      IF (rc < CPIC_SUCCESS) THEN
97         WinMessageBox($DESKTOP,
                        'CPIC Error',$MBOK,
                        'Send returns '&rc);
98         ExitLoop;
99         END;
100        CPICFlush(Conv);
101     END;
102     FClose(inf); 
103
104     IF (rc = CPIC_SUCCESS) THEN
105        CPICPrepareToReceive(Conv);
            -- Indicates Partner may send now.
106        t2 := $NOW;
107        RcvData(w,Conv);
108     END; 
109
110     CPICDeallocate(Conv);
111     WinWriteLn(w,'<<<<<<<<<<<<<<<<<<<<<<<<
                      >>>>>>>>>>>>>>>>>>');
112     WinWriteLn(w,'Elapsed time for outgoing
                   transmission: '&
113                TimeDif(t2,t1,$SECONDS)&'
                seconds');
114     WinWait(w);
115  END;
116
117

プログラムの検討

先行コード・サンプルを説明する検討は次の通りです。

行 42 には、旧式のコードが入っています。このアプリケーションは当初は $CPICConfirm の同期レベルを使用するために作成され、 RcvData はパートナーによる確認をすべて検出して、それを確認しなければなりません。同期レベルが行 80 で $CPICNone に設定されているので、これが行われません。

行 75 〜 93 には、会話セットアップ・コマンドが入っています。 $CPICNone は会話のデフォルトであるので、設定する必要はありません。

行 90 では、CPICAllocate の後に、タイプを受信する準備が設定されます。これは、 CPICPrepareToReceive の呼び出し時に常に実行されるアクションのタイプを指示します。受信でデータが作動可能になると同時に最後のバッファーが送信されるように、フラッシュが選択されました。

ファイル伝送は行 96-105 で行われます。これが、わずか 2 つの CPIC コマンド (CPICSendCPICFlush) によって行なわれる、ことに注意してください。行 15-17 に定義された 1 つのレコードが送信されます。

マップ・ファイル FILEREC.DDF は次の通りです。

1
2    *PARTNER 
3       EBCDIC = FALSE 
4       NON_INTEL = FALSE 
5       CUSTOM_CONVERT = TRUE 
6
7    *FIELDS 
8    LineNbr INTEGER 2 TRUE 
9    Buff ASE_STRING VAR TRUE 
10

行番号と行目次の両方がパートナー・アプリケーションに送信されます。 REXX アプリケーションはバッファーを 1 つのストリングとして取り扱うので、バッファーを戻すことができ、 TSD Developer's Toolkit はこの 2 つのフィールドをもう一度取り出すことができます。

行 104 では、バッファーをフラッシュします。これによって、CPICSend に渡されるデータが即時にパートナーに送信されます。

ファイルの送信の後、パートナーはデータの送信が開始できると通知されます。 RcvData 関数 (行 22) が着信データを操作します。

RcvData は、エラーがある (会話を割り振り解除するパートナーも含む) か、あるいはアプリケーションが再び送信通知を受け取るまで、着信 FILEREC データを受信します。

会話は行 114 で割り振り解除されます。

例題モジュール 2 - FILESND2.KB

これは、2 番目の例題モジュールです。このアプリケーションのゴールは、最初の例題と同じです。この 2 つの相違は、パフォーマンスの向上のために一部のコードが変更されている点です。

FILESND の場合と同じ SDN を FILESND2 でも使用することができます。

FILESND2 の実行

  1. FILESND2 を解析します。
  2. コマンド行で、次を入力します。
    KML FILESND2 FILESND {filename}
  3. アプリケーションの実行後、リストの終わりに経過時間が表示されます。これは、例題モジュール 1 より早いはずです。

ファイル行のリスト

FILESND2.KB のリストは次の通りです。

1
2     -- より効率的な例です。
3     -- 一部の行がコメント化されていることに注意
         してください。これらは元の FILESND.KB から
4     -- のもので古いものです。新しい行は (* NEW *)
         でマーク付けされます。
5
6     KNOWLEDGEBASE FILESND2;
7 
8     ROUTINES
9        PROCEDURE DoConversation(VAL Args:
                                  List of String);
10      (* sdn, infile *)
11
12
13    PRIVATE 
14
15    CONSTANTS
16       CPIC_SUCCESS IS 1;
17
18    TYPES
19       FileRec IS RECORD
20          LineNbr:Integer;
21          Buff:String;
22          END; 
23
24    ROUTINES 
25
26    FUNCTION RcvData(REF w:WINDOW, VAL Conv:
                      Conversation):INTEGER IS
27    VARIABLES
28       totalBuff :FileRec;
29       dataRcvd :integer;
30       statRcvd :integer;
31       reqTSRcvd :integer;
32       rc :integer;
33    ACTIONS
34       IF (not(Known(w))) THEN
35          WinCreateScrollWindow($DESKTOP,w,
36                                $NullHandler,
37                                1,1,67,7,
                                  'FileSnd2','', 0,
                                  $WinBorder+
                                  $WinTitle+
                                  $WinHScroll+
                                  $WinVScroll+
38                                $WinSysMenu+
                                  $WinResize);
39       END;
40       REPEAT
41          rc := CPICReceive(Conv,'FILEREC.DDF',
                              totalBuff,DataRcvd,
                              StatRcvd,ReqTSRcvd);
42          IF (rc > 0) THEN
43          IF ((StatRcvd = $CPICConfirmReceived)or 
44             (StatRcvd=$CPICConfirmSendReceived))
                 THEN
45              rc := CPICConfirmed(Conv);
46          END;
47          totalBuff.buff := StrTrim
                (totalBuff.buff);
48          WinWriteLn(w,totalBuff.lineNbr:5&':
                       '&totalBuff.buff);
49          END;
50       UNTIL ((rc <> 1) OR ((StatRcvd =
                         $CPICSendReceived) OR 
51                    StatRcvd=
                          $CPICConfirmSendReceived)));
52       Exit(rc);
53    END; -- RcvData
54
55
56    ---------------------------------------------
57    -- 説明: 指定されたファイルに読み込み、
         指定された SDN を介して指定されたパートナーに
58    -- 各行を CPIC 経由で送信します。
59    ---------------------------------------------
60    PROCEDURE DoConversation(VAL Args:
                                   List of String) IS
61    VARIABLES
62       Conv :Conversation;
63       fRec :FileRec;
64       ReqTSRcvd :INTEGER;
65       rc :INTEGER;
66       inf :FILE;
67       w :WINDOW;
68       t1,t2 :TIME;
69    ACTIONS
70       t1 := $NOW;
71    IF (ListLength(Args) < 2) THEN
72    WinMessageBox($DESKTOP,'Oops',
                    $MBOK,'KML FILESND 
                    {SDN} {INFILE}');
73       Exit;
74    END; 
75
76    FOpen(inf,Args[2],$Read); 
77
78    rc := CPICInitialize(Conv,Args[1]);
79    IF (rc < CPIC_SUCCESS) THEN
80       WinMessageBox($DESKTOP,'CPIC Error',
                       $MBOK,'Init returns
                           '&rc);
81       Exit;
82    END;
83    rc := CPICSetSyncLevel(Conv, $CPICNone);
84    IF (rc < CPIC_SUCCESS) THEN
85       WinMessageBox($DESKTOP,'CPIC Error',
                       $MBOK,'SSL returns
                           '&rc);
86    END;
87    rc := CPICAllocate(Conv);
88    IF (rc < CPIC_SUCCESS) THEN
89       WinMessageBox($DESKTOP,'CPIC Error',
                       $MBOK,'Allc returns
                           '&rc);
90       Exit;
91    END; 
92    rc := CPICSetPrepareToReceiveType(Conv,
93                                     $CPICPrep
                                       ToReceiveFlush); 
94    IF (rc < CPIC_SUCCESS) THEN
95       WinMessageBox($DESKTOP,'CPIC Error',
                       $MBOK,'SPTR returns
                           '&rc);
96    END; 
97
98    fRec.lineNbr := 0;
99    while (FReadLn(inf,fRec.Buff) > 0) do
100(* NEW *)
101-- ファイルの終わりであるかどうかを判別する
      ことによって、適切な送信タイプを設定する
102-- ことができます。これによって、後から
      CPICPrepareToReceive の呼び出しを回避する
103-- ことができ、ノード・サービス・システムが
      パートナーに余分な送信を行わないように
104-- することができます。
105   IF (FEnd(inf)) THEN
106     CPICSetSendType(Conv,
                        $CPICSendAndPrep
                        ToReceive);
      END;
107   (* END NEW *)
108        fRec.Buff := fRec.Buff & Char(13) &
                           Char(10);
             -- add CR LF
109         fRec.lineNbr := fRec.lineNbr + 1;
110         rc := CPICSend(Conv,
                           'FILEREC.DDF',
                           fRec,
                           ReqTSRcvd); 
111         IF (rc < CPIC_SUCCESS) THEN
112           WinMessageBox($DESKTOP,'CPIC Error',
                           $MBOK,'Send returns
                           '&rc);
         ExitLoop;
113   END;
114-- CM/2 によってバッファリングを行います。
      もう一方の終端には、送信されたバッファー
115-- の同じ番号がまだ表示されています。CM/2 は
      効率のために一部のバッファーをまとめる
116-- ことがあります。
117    (* CPICFlush(Conv); *) 
118
119   END;
120   FClose(inf); 
121
122   IF (rc = CPIC_SUCCESS) THEN
123-- この通知は最後の送信と一緒に送信される
      ので、これを実行する必要はありません。
124   CPICPrepareToReceive(Conv);
   -- パートナーが現在送信できることを示します。--
125     t2 := $NOW;
126     RcvData(w,Conv);
127   END;
128
129   CPICDeallocate(Conv);
130   WinWriteLn(w,'<<<<<<<<<<<<<<<<<<<<<<<<
                    >>>>>>>>>>>>>>>>>>');
131   WinWriteLn(w,'Elapsed time 
                for outgoing transmission: '&
                TimeDif(t2,t1,$SECONDS)&'
                seconds');
      WinWait(w);
132END;

パフォーマンスを向上させるための変更の要約

これまで、このアプリケーションをより早く実行させるための努力は行なわれていません。行 105-108 が追加され、行 117 と 124 が除去されました (コメント化)。

FILESND2.KB で行なわれた変更は次の通りです。

CPIC のデータ・バッファリングでは、その使用をためらう点もあります。一番の問題は、ユーザー・アプリケーションがパートナー・アプリケーションと頻繁に "連絡" しないことです。この例の場合、これは問題になりません。ただし、パートナー・アプリケーションによっては、動的に送信する権限が要求可能であることが必要な場合があります。 その場合には、できるだけ頻繁にパートナー・アプリケーションからフラグを受け取るために、バッファーのフラッシュをコントロールすることがベストです。


Tivoli Service Desk 6.0 Developer's Toolkit レガシー API の手引き

目次に戻る

著作権