第326期 / December 5, 2024

分享到臉書!分享到維特!分享到噗浪!分享到Google+!分享到微博!轉寄友人友善列印

[技術分享] HPE NonStop主機上的現代化開發方式(下)

作者/莊佳哲

[發表日期:2024/12/5]

作者簡歷

作者現職凌群電腦金控軟體研發總處軟體工程師,主要負責期貨系統軟體,專長為COBOL、JAVA、C#軟體開發。

前言

在 NonStop 系統環境中,除了傳統的COBOL開發,Nonstop也有支援現代的開發工具,像是Java、SQL/MX等等。本期將承接上期,接著介紹在NonStop上如何讓Java與Pathway Server結合。

JToolkit:Pathway相關Package

一、Java as pathway server相關


com.tandem.ext.guardian:此Package提供Class執行Guardian File的I/O,包括$RECEIVE。

相關Class:
Receive:包含使用$RECEIVE進行process之間通信的方法。
ReceiveInfo:包含通過call FILE_GETRECEIVEINFO_獲得的$RECEIVE檔案相關資訊。

相關例外處理Class:
ReceiveNoOpeners:表示此server已經沒有被其他程式使用。

二、Java pathsend pathway server相關

com.tandem.tsmp:此Package提供pathsend用的Class。

相關Class:
TsmpServer:包含對pathway serverclass發出請求和接收回答的方法。

相關例外處理Class:
TsmpFileSystemException:表示發生FileSystem錯誤
TsmpReplyException:表示為TsmpServerReply或TsmpGenericServerReply轉換資料時發生錯誤。
TsmpRequestException:表示為TsmpServerRequest轉換資料時發生錯誤。
TsmpRoutUnavailableException:表示因為Rout錯誤所以發送失敗。
TsmpSendException:表示將資料送到TS/MP server時發生錯誤。
TsmpServerException:表示Tsmp Server發生異常。
TsmpServerUnavailableException:表示此Tsmp Server不可使用。

Java as Pathway Server

一、設計server程式


Server程式需要Open $RECEIVE,$RECEIVE用來接收系統訊息和其他程式pathsend來的資料。
以下程式範例與說明:
import com.tandem.ext.guardian.*;

public class TestJava {
  //使用com.tandem.ext.guardian中的Receive物件
  static Receive recv = null;

  public static void main(String[] args){
   //ReceiveInfo包含從$RECEIVE讀取的訊息的相關資訊
   ReceiveInfo ri = null;
   //moreOpeners用來判斷此server是否還在使用中
   boolean moreOpeners = true;
   //countRead用來存放從$RECEIVE讀出的資料長度
   int countRead = 0;
   //countReply用來存放回覆資料的資料長度
   int countReply = 0;
   //msg用來存放從$RECEIVE收到的訊息
   byte[] msg = new byte[2048];
   //sysNum用來存放訊息號碼
   short sysNum = 0;

   /* Open $RECEIVE部分 */
   try {
    //建立Receive實例
    recv = Receive.getInstance();
    //setSystemMessageMask方法設定$RECEIVE要接收那些系統訊息
    //此處設定只接收OPEN、CLOSE、ABORTDIALOG、CANCEL的訊息
    recv.setSystemMessageMask(Receive.SMM_OPEN | Receive.SMM_CLOSE | Receive.SMM_ABORTDIALOG | Receive.SMM_CANCEL);
    //Open $RECEIVE FILE
    recv.open();
   }catch (GuardianException ex) {
    //Open $RECEIVE過程中出現Guardian系統錯誤,輸出錯誤訊息後結束程序
    System.out.println("Open $Receive failed!");
    System.out.println(ex.getMessage());
    System.exit(1);
   }catch (Exception e) {
    //出現其他錯誤,輸出錯誤訊息後結束程序
    e.printStackTrace();
    System.exit(1);
   }

   do {
    try {
     //從$RECEIVE讀取資料,可能是系統訊息或是其他程式PATHSEND來的訊息
     countRead = recv.read(msg, msg.length);
     //取得最後一次成功執行read方法的相關訊息,包括IO Type、檔案代號等等資訊
     ri = recv.getLastMessageInfo();

     //判斷是不是系統訊息
     if (ri.isSystemMessage()) {
      /* 一段時間沒新訊息 關閉server */
      //取得訊息號碼,此號碼為訊息的類型,若不是系統訊息,號碼 = 0
      sysNum = ri.getSystemMessageNumber(msg);
      //判斷是不是OPEN訊息
      if (sysNum != ReceiveInfo.SYSMSG_OPEN) {
       //非OPEN訊息,剩餘可能為CLOSE、ABORTDIALOG、CANCEL,收到後退出程式
       System.out.println("exit process!");
       System.exit(1);
      }
     }else {
      /* 收到其他程式pathsend來的訊息 */

      // TODO 收到資料後要做的事

     //回覆資料的BUFFER
     byte[] replyArea = "reply message...".getBytes();
     //回覆結果
     countReply = recv.reply(replyArea, replyArea.length, GError.EOK);
     }
    }catch (ReceiveNoOpeners ex) {
     //此SERVER已經沒有其他程式OPEN了,結束程式
     moreOpeners = false;
    }catch (GuardianException ex) {
     //處理過程中有Guardian Error
     System.out.println(ex.getMessage());
    }catch (Exception e) {
     //其他異常,結束程式
     e.printStackTrace();
     System.exit(1);
    }
   }while (moreOpeners); //判斷此SERVER是否還在被其他程式OPEN,是的話繼續迴圈執行
  }
}

二、在pathway設定server

pathcom設定範例:
SET SERVER AUTORESTART 3
SET SERVER CPUS (1:0)
SET SERVER CREATEDELAY 0 SECS
SET SERVER DEBUG OFF
SET SERVER DELETEDELAY 2 MINS
SET SERVER HIGHPIN ON
SET SERVER HOMETERM \NSX.$VHS3
SET SERVER LINKDEPTH 1
SET SERVER MAXLINKS 2
SET SERVER MAXSERVERS 5
SET SERVER NUMSTATIC 0
SET SERVER PRI 180
SET SERVER SECURITY "U"
SET SERVER TMF ON
SET SERVER VOLUME SAMPW

以下是與設定COBOL SERVER時較為不同的地方
==設定要執行OSS系統下的程式
SET SERVER PROCESSTYPE OSS
==設定要使用的當前工作目錄,必須使用絕對路徑,以”/”開頭
SET SERVER CWD /java/sam
==設定執行的程式,要指定java執行檔
SET SERVER PROGRAM /usr/tandem/nssjava/jdk110_l11/bin/java
==設定執行程式的參數,以範例來說相當於輸入指令java -jar TestJava-1.4.jar,實際上是執行TestJava-1.4.jar這個server程式
SET SERVER ARGLIST -jar,TestJava-1.4.jar

==SERVER ENV設定該server使用的環境變數
SET SERVER ENV CLASSPATH = /java/sam/enslib/enslib.jar:/usr/tandem/javaexth11/&
lib/tdmext.jar:
SET SERVER ENV _RLD_LIB_PATH=/usr/tandem/javaexth11/lib:/usr/tandem/jdbcMx/T12&
75L37/lib
SET SERVER ENV JAVA_HOME=/usr/tandem/nssjava/jdk110_l11

==因為OSS程式無法輸出訊息到VHS,所以若是要輸出LOG訊息的話要另外指定STDERR、STDOUT要輸出到哪個檔案,這樣使用System.out.println時就會輸出到該檔案
SET SERVER STDERR /java/sam/jpwlog.txt
SET SERVER STDOUT /java/sam/jpwlog.txt

Java Pathsend Pathway Server
以下Java pathsend程式範例:
import com.tandem.tsmp.TsmpServer;

public class Jpathsend {
 public static void main(String[] args){
  //pmonName設定Guardian系統中,要pathsend到哪個pathmon process
  String pmonName = "$YTPW";
  //svrClassName設定要pathsend到哪個server class
  String svrClassName = "JAVASVR";
  //建立TsmpServer物件,帶入參數pmonName和svrClassName,用來執行pathsend server class
  TsmpServer getServer = new TsmpServer(pmonName, svrClassName);
  //request用來放要送到server class的資料
  byte[] request = new byte[200];
  //greply用來放從server class回傳的資料
  byte[] greply = new byte[4096];

  try {
   //進行pathsend動作,送出request,server class回傳的資料放在greply
   getServer.service(request, request.length, greply);
  }catch (TsmpSendException tse) {
   //pathsend送到server class時失敗
   System.out.println("send error!");
   tse.printStackTrace();
  }catch (Exception e) {
   //其他異常
   e.printStackTrace();
  }

   // TODO 開始處理pathsend回來的資料
   System.out.println(new String(greply));
  }
}

結論

透過HPE提供的JToolkit,我們在NonStop上能夠簡單並快速的使用Java開發像是I/O Enscribe File、Pathsend Pathway Server等等與Guardian系統有關的程式,擺脫過去只能選擇使用COBOL開發的情況。(全文結)

參考資料

.NSJ 11 User Guide
.HPE JToolkit for NonStop Server for Java 11 Programmer's Reference