今日の時点でもう期間が過ぎてしまっているのですが、はじめてAdvent Calendarの記事を投稿します。
- NTTデータイントラマート Advent Calendar 2020
やりたかったこと
あるFormaアプリ(A)でアップロードしたファイル一覧を、別のFormaアプリ(B)のグリッドテーブルでダウンロードしたり、選択したりしたかったのです。
JavaEE開発モデルやスクリプト開発モデルを用いて専用の画面を作成すれば、すぐに実現可能と思われるのですが、それだとシステム停止を伴うデプロイ作業が発生してしまいます。システム停止調整となると・・・社内事情やユーザ事情などいろんなことがあり、それだけは避けなければならない・・・。
したがってIM-FormaDesignerなど、デプロイを伴わない機能だけで要件を満たし、迅速に対応する必要がありました。
- IM-FormaアプリAで添付ファイルをアップロード
- IM-FormaアプリB側で、A側のファイルを取得し、ダウンロードURLを生成
- これをJava開発モデルやスクリプト開発モデルではなく、warファイル差し替えを行わずデプロイを伴わない下記の方法で実現したい
- IM-FormaDesigner
- IM-LogicDesigner
- データソース定義
概要図
成果物(gifアニメーション)
成果物の各種定義
- 下記よりダウンロードできます
やったこと
ダウンロード用ページの解析
IM-FormaDesignerからファイルをダウンロードするには、独自のダウンロード用ページを経由するか、
標準のファイルダウンロード部品のページを経由する必要があります。
独自のダウンロード用ページは前述したとおりデプロイが必要となるので利用ができません。
そこで、標準のファイルダウンロードページを経由させることにします。
標準のファイルダウンロードページ:forma/designer/types/product/72/fileupload/download
しかし、ここに然るべきパラメータをfile_id
やapplication_id
を渡すだけでは適切に動作しません。
im_mark
という(おそらく)セッションごとに自動付与されるパラメータを渡してあげる必要があります。
im_mark
はどうやったら取得できるのか?これを調べる必要があります。
intra-mart社が作成したソースが格納されているテナントID/WEB-INF配下をdownloadなどのキーワードでgrep検索してみます。
そうすると、WEB-INF/jssp/product/src/forma/designer/types/product/72/fileupload
配下にいい感じのコードが見つかります。
- fileupload_savefile.jsの48行目付近
var downloadUrl = new URL('forma/designer/types/product/72/fileupload/download');
downloadUrl.setArgument('application_id', request.applicationId);
downloadUrl.setArgument('insert_id', request.insertId);
downloadUrl.setArgument('upload_item_id', request.uploadItemId);
downloadUrl.setArgument('imfr_process_key', request.processKey);
downloadUrl.setArgument('file_id', FRCryptionUtil.encrypt(result.fileId));
downloadUrl.setArgument('type', result.fileInfo.type);
// ファイル情報の返却
response.sendMessageBodyString(ImJson.toJSONString([{
name : oFile.getFileName(),
application_id : request.applicationId,
insert_id : request.insertId,
process_key : request.processKey,
input_id : request.uploadItemId,
file : {
id : result.fileId,
encrypt_id : FRCryptionUtil.encrypt(result.fileId),
type : result.fileInfo.type,
size : result.fileInfo.file_size,
name : oFile.getFileName(),
display_size : displaySize(result.fileInfo.file_size),
notes : request.fileNotes,
record_date : Procedure.imfr_date_utils.getDisplayDatetimeFormat(recordDate,
formats.IM_DATETIME_FORMAT_DATE_STANDARD, formats.locale),
record_time : Procedure.imfr_date_utils.getDisplayDatetimeFormat(recordDate,
formats.IM_DATETIME_FORMAT_DATE_STANDARD + ' ' + formats.IM_DATETIME_FORMAT_TIME_STANDARD, formats.locale),
download_url : downloadUrl.location(),
imageThumbnailPreview : isImageThumbnailPreview
}
}]));
どうやら、URLクラスオブジェクトに然るべきパラメータを渡すことでダウンロード用のURLを生成しているようです。
そこで、このソースを元に、LogicDesignerのJavaScript定義を作成し、IN/OUTを設定します。
ロジックフローの作成
function run(input) {
var downloadUrl = null;
var downloadUrlStr = "";
var downloadUrlForATag = "";
var errorFlg = false;
var errorMsg = "";
try {
downloadUrl = new URL('forma/designer/types/product/72/fileupload/download');
downloadUrl.setArgument('application_id', input.applicationId);
downloadUrl.setArgument('insert_id', input.insertId);
downloadUrl.setArgument('upload_item_id', input.uploadItemId);
downloadUrl.setArgument('imfr_process_key', input.processKey);
downloadUrl.setArgument('file_id', FRCryptionUtil.encrypt(input.fileId));
downloadUrl.setArgument('type', input.type);
} catch(e) {
errorFlg = true;
errorMsg = e.message;
} finally {
if(!errorFlg) {
downloadUrlStr = downloadUrl.location();
downloadUrlForATag = "<a href='" + downloadUrlStr + "'>" + input.fileName + "</a>";
}
}
return {
downloadUrl: downloadUrlStr,
errorFlg: errorFlg,
errorMsg: errorMsg,
downloadUrlSource: downloadUrlForATag
};
}
これでダウンロードURL作成の準備が完了しました。
あとは、LogicDesignerで下記のような処理を実装し、データソース定義経由で画面に返してあげればOKです
- SQL定義を用いて
IMFR_T_FILEUPLOAD
テーブルから、トランザクションのINSERT_ID
とAPPLICATION_ID
を元にファイルIDやファイル名を取得する - 繰り返しタスクで、上記結果オブジェクトをループ
- 各ファイルIDやファイル名ごとに、ダウンロードURL作成用のJavaScriptを実行し、URLを取得。データを返却
- データをリスト形式でpushしていく
- リスト形式のデータを画面に返却する
画面イメージ
これで、システム停止を行わず(デプロイせず)に、IM-FormaDesigner, LogicDesignerのみで対応を行うことができました。
年末にこの課題対応ができて一安心です。
最後に注意点
本件はあくまでもデプロイを伴うシステム変更が困難である場合の奥の手です。
本当にこの内容で対応を実施すべきかどうかを熟考した上で適用すべきと考えます。
申し訳ありませんが、この対応によって発生した障害等について、一切責任を負いませんので、ご了承ください。