ENGINEER BLOG

ENGINEER BLOG

IBM i(AS400)とFlaskでWebアプリ!

こんにちは。SCI本部の森です。
エンジニアブログ初登場です。
今回はIBM i のお話です。
「IBM i って古いシステムだろ、俺には関係ないぜ。」
と思った方、まあそう言わずにお付き合いください。

1.それぞれが抱える課題

私は普段IBM i の保守・開発を行っているのですが、その中でいくつかの課題によく直面します。

■ユーザーの抱える課題

  • エミュレータが入っているPCがないと業務ができない。
  • 若い人がエミュレータ画面(黒背景に緑の文字)に抵抗を感じる。

■技術者の抱える課題

  • ベテラン技術者によるシステムの属人化。
  • 若手技術者不足により知識継承が困難。

IBM i は確かに歴史のあるシステムですが、保守の面で優位性があり使い続けているお客様も多い。
これらの課題を解決できないか。。。

2.解決の糸口

IBMの主催する「オープンソース協議会 IBM i」で以前こんな発表がありました。

IBM i で Python やってみた(ティアンドトラスト株式会社 様)

IBM i にPython!?しかもDB接続までしている!
そうなんです。IBM i と言えば言語はRPGですが、それしか動かないわけではないんです。

Pythonと言えば

  • O’Reilly 学びたいプログラミング言語 1位 (2021/1時点)
  • TIOBE プログラミング言語人気ランキング 1位 (2021/6時点)

Pythonの人気はかつてないほどに高まっている・・・。
そうだ!

IBM i でPythonを動かしてWebブラウザから操作できるようにしたら、
さっきの課題まるっと解決できるのでは?
ということで、今回はWebブラウザからIBM i のDBを覗いてみたいと思います。

3.作ってみよう!

システム構成

  • システム構成図

システム構成図

  • ファイル構成
project
├── config                   # 各サーバの設定ファイル
│   ├── gunicorn_settings.py
│   └── nginx.conf
│
├── logs                     # ログファイル
│   ├── gunicorn-access.log
│   └── gunicorn-error.log
│
├── templates                # 各画面のhtmlファイル
│   ├── entries
│   │   ├── detail.html
│   │   └── search.html
│   └── layout.html
│
├── db_view.py               # メインとなるアプリケーション
└── sql.py                   # SQL実行用アプリケーション

ファイルの内容

  • メインとなるアプリケーションファイル
    今回は簡単にDBの検索画面、検索結果の詳細画面のみの構成となっています。
# project > db_view.py

from flask import Flask
from flask.templating import render_template
from flask import request
from sql import select            # SQL実行用アプリケーションのインポート

# 商品の検索画面
app = Flask(__name__)
@app.route('/')
def search_entries():
    return render_template('entries/search.html')

# 商品の詳細画面
@app.route('/detail', methods=['POST'])
def detail_entries():
    code = request.form['code']   # code:検索画面で入力されたコード
    result = select(code)
    entries=result[0]
    return render_template('entries/detail.html', entries=entries)

if __name__ == "__main__":
    # ネットワーク内の他のコンピューターからアクセス
    app.run(host="0.0.0.0", debug=True)
  • SQL実行用アプリケーションファイル
    今回は試作のため検索画面で入力されたコードをSQLのWHERE句に直接入れていますが、
    外部に公開する際はSQLインジェクション含め、セキュリティ面での考慮が必要です!
# project > sql.py

import ibm_db_dbi as db
import io, sys

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

def select(code) :
    # IBM i のDBに接続
    conn = db.connect("DATABASE=*LOCAL;","USERID", "PASSWORD")
    cursor = conn.cursor()

    # 検索画面で入力されたコードをWHERE句に設定
    # 外部に公開する際はセキュリティ面での考慮が必要です!
    sql = "SELECT * FROM XXXXLIB.TESTMSP WHERE TPRDCD=" + str(code)
    cursor.execute(sql)
    r = cursor.fetchall()
    return r
  • NGINX設定ファイル
# project > config > nginx.conf

worker_processes 1;

events {
    worker_connections 512;
}

http {
    server {
        listen 9111;
        server_name DB-VIEW-NGINX;
        charset UTF-8;

        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Host $host;

        location / {
            proxy_pass http://127.0.0.1:9888;
        }
    }
}

  • Gunicorn設定ファイル
# project > config > gunicorn_settings.py

import os

bind = '127.0.0.1:' + str(os.getenv('port', 9888))
proc_name = 'DB-View-Flask'
workers = 1
errorlog = '/home/xxxx/project/logs/gunicorn-error.log'
accesslog = '/home/xxxx/project/logs/gunicorn-access.log'

※htmlファイルに関しては簡易的なものなので割愛します。

  • 今回テストとして使用するマスタ
    例の黒画面です。

DDS

RUNQRY

4.動かしてみよう!

動かしてみよう!ということで、まずはプロセスを起動します。

# Web Serverの起動
nginx -c /home/mori/project/config/nginx.conf

# App Serverの起動
gunicorn db_view:app -c config/gunicorn_settings.py --reload

次にWebブラウザからIBM i のプライベートIPアドレスにアクセスします。
(ポートは設定ファイルに記述したものです。)

URL入力

いざ、実行!

アクセス

画面が表示されました!
(あまりに簡易的ですが、ご愛嬌ということで。)
さっそく商品を検索してみましょう。

コード入力

検索 検索~!

詳細画面

無事表示されました!

Google Chromeでスマートフォンの画面にエミュレートしたイメージ図がこちらになります。

スマホ

IBM i をスマートフォンから操作する日も近いかもしれません!

5.最後に

いかがでしたでしょうか。
IBM i の黒画面がWebアプリケーションとして生まれ変わりました。

ベテランのIBM i とルーキーのPython君のコンビ。
ここからどんなことができるでしょうか、夢が広がりますね。
更なる発展を目指していきたいと思います!

最後までお読みいただき、ありがとうございました。