このブログエントリの続きのような、関係ないような内容です:
IBM COBOL for Linux 1.1 を使ってみた

もともとは「過去の COBOL 資産をウェブやクラウド環境で活用するにはどうすればいい?」かを考えていて、最初は CGI 化してウェブからうまく呼び出して使えないか、、、と検討していたのですが、「活用」と呼ぶにはそのための準備がなかなかに面倒そうで頓挫していました。要は COBOL エンジニアが少なくなってメンテナンスも難しくなっている昨今、COBOL 資産をどうやって今の環境で活用するか、というテーマは実際に検討してもキレイな答を見つけるのが難しいことを再認識する結果となっています。

といいつつ、「難しいですね~」で終わらせるのもシャクなので自分なりの答を用意しました。それがブログタイトルでもある Node.js の child_process を使う方法です。


Node.js + Express で普通にウェブアプリを作りつつ、COBOL 資産をサブルーチンのように(子プロセスとして)呼び出して動かし、その実行結果をウェブのレスポンスとする、という方法です。その子プロセスとしてコマンドを動かす際に child_process を利用します。ぶっちゃけ COBOL 資産でなくても応用の効く泥臭い方法ですが、コマンドラインパラメータを受け取って動き、結果を stdout へ出力する一般的なタイプのバイナリであれば再コンパイル無しで使えるという大きなメリットのあるウェブ化手法といえます。

言葉で説明するよりも実際のコードを見ていただくのが早いと思っています。まず COBOL 資産(資産といえる代物じゃないけど)として先日紹介した COBOL 版 Hello World を使います。特にこのファイルは x86_64 Linux 向けの実行可能バイナリになっているので、ダウンロードして `$ chmod +x hello` するだけで動きます(`$ ./hello` で "Hello World!" と出力するだけですが)。とりあえず、これを COBOL 資産とみなすことにします。


そしてこのコマンドを呼び出してレスポンスを返すウェブアプリケーションを Node.js + Express で作ります:
https://github.com/dotnsf/hello-cobol-web


アプリケーションの実体となる app.js の中は以下のようになっています:
//. app.js
var express = require( 'express' ),
    { exec } = require( 'child_process' ),
    app = express();
var command = '/home/dotnsf/src/hello/hello';

app.use( express.Router() );

app.get( '/', function( req, res ){
  res.contentType( 'text/plain; charset=utf-8' );
  
  exec( command, function( err, result, stderr ){
    if( err ){
      res.status( 400 );
      res.write( err.message );
      res.end();
    }else if( stderr ){
      res.status( 400 );
      res.write( stderr );
      res.end();
    }else{
      res.write( result );
      res.end();
    }
  });
});

var port = process.env.PORT || 8080;
app.listen( port );
console.log( "server starging on " + port + " ..." );

まず赤字部分で child_process ライブラリを呼び出し、シェルコマンドを実行する準備をしています。次に緑字部分で実際に呼び出すコマンド(この場合は上記 hello コマンド)をフルパスで指定します(コマンドラインパラメータが必要な場合はこのコマンド文字列に含めておきます)。

そして実際にコマンドを呼び出しているのが青字部分です。GET / の HTTP リクエストを受けたら hello コマンドを(JavaScript らしく)非同期に実行し、その実行時や実行結果にエラーがあった場合は HTTP ステータスコード 400 で、なかった場合は(デフォルトの)HTTP ステータスコード 200 でそれぞれの結果を text/plain で返すコードになっています。

上述のコードを Node.js で実行し、GET / を実行すると(hello コマンドのフルパスやパーミッションを間違えていなければ)COBOL 資産の実行結果が HTTP の結果として "Hello World!" と表示されるはずです:
2021042601


専用コマンドのインストール部分が、特に有償ツールなどの場合だとコンテナ化までは難しいかもしれません。ただ COBOL 資産に限らず、形態素解析エンジンのような専用インストールが必要なコマンド・アプリケーションをウェブ化するようなケースでも応用できる便利な方法の紹介でした。