001/* 002 * Copyright (c) 2017 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.fileexec; 017 018import java.nio.file.Files; 019import java.nio.file.Path; 020import java.util.Arrays; 021 022import static org.opengion.fukurou.fileexec.CommandLine.GE70; // enum を簡素化して使用するための定義 023 024/** 025 * FileExec は、処理の中心で、デーモン一つに対応する処理開始クラスです。 026 * 027 *<pre> 028 * このクラスは、ファイルスキャンのフォルダ単位に、起動され、ファイルのイベントを処理します。 029 *</pre> 030 * 031 * @og.rev 7.0.0.0 (2017/07/07) 新規作成 032 * 033 * @version 7.0 034 * @author Kazuhiko Hasegawa 035 * @since JDK1.8, 036 */ 037public class FileExec { 038 private static final XLogger LOGGER= XLogger.getLogger( FileExec.class.getName() ); // ログ出力 039 040 /** システム依存の改行記号(String)。 */ 041 public static final String CR = System.getProperty("line.separator"); 042 043 private final TBL_GE71 tableGE71 ; // 6.9.7.0 (2018/05/14) PMD 044 045 private final String systemId ; // システムID 046 private final String rsrvNo; // 予約番号 047 private final String execId; // 処理ID 048 049 private final String fileFltr ; // 検索条件 050 051 private final BasePath basePath ; // 各種パスを管理しているクラス 052 053 private final FileWatch fWatch ; // 取込フォルダをイベントで監視する 054 055 /** 056 * コマンドラインを引数に取るコンストラクター 057 * 058 * ファイルの監視を開始します。 059 * 060 * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加 061 * 062 * @param cmndLine コマンドラインオブジェクト 063 */ 064 public FileExec( final CommandLine cmndLine ) { 065 LOGGER.debug( () -> "② CommandLine=" + cmndLine ); 066 067 systemId = cmndLine.getValue( GE70.SYSTEM_ID ); // システムID 068 rsrvNo = cmndLine.getValue( GE70.RSRV_NO ); // 予約番号 069 execId = cmndLine.getValue( GE70.EXECID ); // 処理ID 070 fileFltr = cmndLine.getValue( GE70.FILE_FILTER ); // 検索条件 071 072 basePath = new BasePath( 073 cmndLine.getValue( GE70.DIR_BASE ) , // 取込ベースフォルダ 074 cmndLine.getValue( GE70.DIR_SUB ) , // 取込サブフォルダ 075 cmndLine.getValue( GE70.DIR_WORK ) , // 処理フォルダ(WORK) 076 cmndLine.getValue( GE70.DIR_BKUP_OK ) , // 処理済フォルダ(正常) 077 cmndLine.getValue( GE70.DIR_BKUP_NG ) ); // 処理済フォルダ(異常) 078 079 tableGE71 = new TBL_GE71( systemId,rsrvNo,execId ); // 6.9.7.0 (2018/05/14) PMD 080 081 fWatch = new FileWatch( basePath.SUB_PATH ); // サブフォルダをイベントで監視する 082 } 083 084 /** 085 * このコマンドに対応するフォルダの監視を開始します。 086 * 087 * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加 088 */ 089 public void watchStart() { 090 LOGGER.debug( () -> "④ [watchStart()]" ); 091 092 fWatch.setEventKinds( FileWatch.CREATE , FileWatch.MODIFY ); 093 fWatch.setPathMatcher( new PathMatcherSet().addFileName( fileFltr ) ); // ファイルの検索条件 094 fWatch.callback( (event,fPath) -> checkFile( event,fPath ) ); 095 fWatch.start(); 096 } 097 098 /** 099 * このコマンドに対応するフォルダの監視を終了します。 100 * 101 * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加 102 */ 103 public void watchStop() { 104 LOGGER.debug( () -> "③ [watchStop()]" ); 105 106 fWatch.stop(); 107 } 108 109 /** 110 * 更新されたファイルをチェックします。 111 * 112 * ※ バックアップ処理してから、DB取り込み処理を行います。 113 * よって、DB登録処理中にエラーが発生した場合でも、バックアップ済みです 114 * 115 * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加 116 * 117 * @param event 発生イベントの名称 118 * @param filePath ファイルパス(相対パス) 119 */ 120 private void checkFile( final String event,final Path filePath ) { 121 Path bkup = null; 122 Path okFile = null; 123 Path ngFile = null; 124 String errMsg = ""; 125 126 try { 127 // FileUtil.stablePath は、書き込まれている途中かもしれないので、安定するまで待つ。 128 if( FileUtil.stablePath( filePath ) ) { 129 LOGGER.debug( () -> "⑤ event=" + event + " , Path=" + filePath ); 130 131 // ワークへ移動してから、DB取り込み処理を行います。 132 bkup = FileUtil.backup( filePath,basePath.WORK_PATH ); // WORKに移動します。 133 134 final String tmStr = StringUtil.getTimeFormat(); // 開始時刻 135 136 final AppliExec appli = AppliExec.newInstance( systemId,execId ); 137 138 final int suKekka = appli.exec( bkup ); 139 140 final String fgtKan ; // 取込完了フラグ 1:処理中 2:済 7:デーモンエラー 8:アプリエラー 141 if( suKekka >= 0 ) { 142 okFile = FileUtil.backup( bkup,basePath.OK_PATH ); // 処理済OKフォルダに移動 143 fgtKan = "2" ; 144 } 145 else { 146 ngFile = FileUtil.backup( bkup,basePath.NG_PATH ); // 処理済NGフォルダに移動 147 fgtKan = "8" ; 148 } 149 150 tableGE71.dbInsert( fgtKan , tmStr , filePath , okFile , ngFile , suKekka , errMsg ); 151 152 LOGGER.info( () -> "DAT execute. " + filePath + " , FGTKAN=" + fgtKan + " , kensu=" + suKekka ); 153 } 154 else { 155 // エラーにせず、保留にします。 156 LOGGER.info( () -> "checkFile Not stablePath. " + filePath ); 157 } 158 } 159 catch( final Throwable th ) { 160 // MSG0021 = 予期せぬエラーが発生しました。\n\tメッセージ=[{0}] 161 errMsg = MsgUtil.errPrintln( th , "MSG0021" , filePath ); 162 163 // 6.9.8.0 (2018/05/28) FindBugs: メソッド呼び出しは非 null パラメータに対して null を渡している 164// if( Files.exists( bkup ) ) { // WORKに移動するところまでは、成功しており、その後の、移動ができていない。 165 if( bkup != null && Files.exists( bkup ) ) { // WORKに移動するところまでは、成功しており、その後の、移動ができていない。 166 ngFile = FileUtil.backup( bkup,basePath.NG_PATH ); // 処理済NGフォルダに移動 167 } 168 169 tableGE71.dbInsert( "7" , StringUtil.getTimeFormat() , filePath , null , ngFile , -1 , errMsg ); // -1 は、エラーを示します。 170 } 171 } 172 173 /** 174 *このクラスの文字列表現を返します。 175 * 176 * @return クラスの文字列表現 177 */ 178 @Override 179 public String toString() { 180// return systemId + " , " + execId ; 181 return String.join( " , " , systemId , rsrvNo , execId ); // 6.9.7.0 (2018/05/14) PMD 182 } 183 184 /** 185 * GE71 実行結果をデータベースに書き込む内部クラスです。 ( 6.9.7.0 (2018/05/14) PMD ) 186 */ 187 private static final class TBL_GE71 { 188 private static final String[] KEYS = new String[] { "SYSTEM_ID","RSRV_NO","EXECID","FGTKAN","TMSTR","TMEND" 189 , "FILE_IN","FILE_OK","FILE_NG","SUTORI ","ERRMSG " 190 , "DYSET","DYUPD" }; 191 private static final String[] CON_KEYS = new String[] { "FGJ","PGSET" ,"PGUPD" }; 192 private static final String[] CON_VALS = new String[] { "1" ,"FileExec","FileExec" }; 193 194 private static final String INS_QUERY = DBUtil.getInsertSQL( "GE71",KEYS,CON_KEYS,CON_VALS ); 195 196 private final String systemId ; // システムID 197 private final String rsrvNo; // 予約番号 198 private final String execId ; // 処理ID 199 200 /** 201 * GE71 データベースにインサート処理を行うクラスのコンストラクター 202 * 203 * @param sysId システムID 204 * @param rsNo 予約番号 205 * @param exId 処理ID 206 */ 207 public TBL_GE71( final String sysId , final String rsNo ,final String exId ) { 208 systemId = sysId ; 209 rsrvNo = rsNo ; 210 execId = exId; 211 } 212 213 /** 214 * データベースにインサート処理を行います。 215 * 216 * @og.rev 6.8.1.5 (2017/09/08) LOGGER.debug 情報の追加 217 * 218 * @param fgtKan 取込完了フラグ 219 * @param tmStr 開始時刻 220 * @param fIn 取込ファイルパス 221 * @param fOk 処理済OKファイルパス 222 * @param fNg 処理済NGファイルパス 223 * @param sutori 取込数 224 * @param errMsg エラーメッセージ 225 */ 226 public void dbInsert( final String fgtKan , final String tmStr , final Path fIn , final Path fOk , final Path fNg , final int sutori , final String errMsg ) { 227 final String NOW = StringUtil.getTimeFormat(); 228 229 final String fileIn = fIn == null ? "" : fIn.toString() ; 230 final String fileOk = fOk == null ? "" : fOk.toString() ; 231 final String fileNg = fNg == null ? "" : fNg.toString() ; 232 233 // GE71 テーブルのカラム 234 final String[] values = new String[] { 235 systemId // システムID SYSTEM_ID 236 , rsrvNo // 予約番号 RSRV_NO 237 , execId // 処理ID EXECID 238 , fgtKan // 取込完了フラグ FGTKAN 239 , tmStr // 開始時刻 TMSTR 240 , NOW // 完了時刻 TMEND 241 , fileIn // 取込ファイル FILE_IN 242 , fileOk // 処理済OKファイル FILE_OK 243 , fileNg // 処理済NGファイル FILE_NG 244 , String.valueOf( sutori ) // 取込件数 SUTORI 245 , errMsg // エラーメッセージ ERRMSG 246 , NOW // 登録日時 DYSET 247 , NOW // 更新日時 DYUPD 248 } ; 249 250 LOGGER.debug( () -> "⑥ GE71.dbInsert query=" + INS_QUERY + "\n\t values=" + Arrays.toString( values ) ); 251 252 DBUtil.execute( INS_QUERY , values ); 253 } 254 } 255}