001/* 002 * Copyright (c) 2009 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.hayabusa.mail; 017 018import java.util.ArrayList; 019import java.util.List; 020import java.util.Arrays; 021import java.util.concurrent.ConcurrentMap; // 6.4.3.3 (2016/03/04) 022import java.util.concurrent.ConcurrentHashMap; // 6.4.3.3 (2016/03/04) 023 024import org.opengion.fukurou.db.DBUtil; 025import org.opengion.fukurou.mail.MailTX; 026import org.opengion.fukurou.system.LogWriter; 027import org.opengion.fukurou.system.DateSet; // 6.4.2.0 (2016/01/29) 028import org.opengion.fukurou.util.StringUtil; 029import org.opengion.hayabusa.common.HybsSystem; 030import static org.opengion.fukurou.system.HybsConst.CR ; // 6.1.0.0 (2014/12/26) 031import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring 032 033/** 034 * パッチによるメール送信の実装クラスです。 035 * 送信デーモンはパラメータテーブル(GE30)を監視して、新規のデータが登録されたら、 036 * そのデータをパラメータとしてメール合成処理メソッドに渡して合成を行って送信します。 037 * 最後に、処理結果を受取って、パラメータテーブルの状況フラグを送信済/送信エラーに更新します。 038 * エラーが発生した場合、エラーテーブルにエラーメッセージを書き込みます。 039 * 040 * @og.rev 5.9.26.0 (2017/11/02) 子クラスで利用する定数をprivateからprotectedに変更 041 * @og.group メールモジュール 042 * 043 * @version 4.0 044 * @author Sen.Li 045 * @since JDK1.6 046 */ 047public class MailManager_DB extends DefaultMailManager { 048// // 5.9.26.0 (2017/11/02) 子クラスで利用定数を、privateからprotectedに変更 049// // 5.2.0.0 (2010/09/01) Ver4互換モード対応 050// // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 051// private static final String H_TXT = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "HEADER" : "H_TXT"; 052// private static final String F_TXT = HybsSystem.sysBool( "VER4_COMPATIBLE_MODE" ) ? "FOOTER" : "F_TXT"; 053 054 // 5.2.0.0 (2010/09/01) Ver4互換モード対応 055 // 6.4.1.1 (2016/01/16) selGE30 → SEL_GE30 , insGE36 → INS_GE36 , updGE30 → UPD_GE30 refactoring 056 // 6.9.5.0 (2018/04/23) VER4_COMPATIBLE_MODE 廃止 057// protected static final String SEL_GE30 = "SELECT UNIQ,PTN_ID,FROM_ID,TO_ID,CC_ID,BCC_ID,"+H_TXT+","+F_TXT 058// // 5.9.32.0 (2018/05/01) 送信件数制限 059// protected static final String SEL_GE30 = "SELECT UNIQ,PTN_ID,FROM_ID,TO_ID,CC_ID,BCC_ID,H_TXT,F_TXT" 060// + ",PARAM0,PARAM1,PARAM2,PARAM3,PARAM4,PARAM5,PARAM6,PARAM7,PARAM8,PARAM9" 061// + ",ATTACH1,ATTACH2,ATTACH3,ATTACH4,ATTACH5" 062// + " FROM GE30" 063// + " WHERE SYSTEM_ID =? AND FGJ='1'" 064// + " AND (SNDTIME IS NULL OR SNDTIME <= ? )"; // 5.9.18.0 (2017/03/02) 065 066 // 5.9.32.0 (2018/05/02) 1回辺りの送信件数制限 0以下の場合は制限なし 067 private static final String SEND_LIMIT = HybsSystem.sysInt( "MAIL_DAEMON_LIMIT" ) < 1 068 ? "" 069 : (" WHERE MAILDB.ROW_NUM <= " + HybsSystem.sys( "MAIL_DAEMON_LIMIT" )); 070 071 // 5.9.32.0 (2018/05/01) 送信件数制限 072 /** GE30 検索文 */ 073 protected static final String SEL_GE30 = "SELECT * FROM (" 074// +"SELECT UNIQ,PTN_ID,FROM_ID,TO_ID,CC_ID,BCC_ID,"+H_TXT+","+F_TXT 075 +"SELECT UNIQ,PTN_ID,FROM_ID,TO_ID,CC_ID,BCC_ID,H_TXT,F_TXT" 076 +",PARAM0,PARAM1,PARAM2,PARAM3,PARAM4,PARAM5,PARAM6,PARAM7,PARAM8,PARAM9" 077 +",ATTACH1,ATTACH2,ATTACH3,ATTACH4,ATTACH5" 078 +",row_number() over (order by uniq) as ROW_NUM " // 5.9.32.0 (2018/05/02) 079 + " FROM GE30" 080 + " WHERE SYSTEM_ID =? AND FGJ='1'" 081 + " AND (SNDTIME IS NULL OR SNDTIME <= ? )" 082// + ") as MAILDB " 083 + ") MAILDB " // 5.10.7.0 (2019/01/11) asはoracleでエラーになるので除外 084 + SEND_LIMIT; 085 086 /** GE36 インサート文 */ 087 protected static final String INS_GE36 = "INSERT INTO GE36(PARA_KEY,ERRMSG,DYSET,USRSET,PGUPD,SYSTEM_ID,FGJ)" 088 + " VALUES(?,?,?,?,?,?,'1')"; 089 090 private static final String UPD_GE30 = "UPDATE GE30 SET FGJ= ? WHERE UNIQ = ? "; 091 092 /** 送信状態 */ protected static final String SNED_OK = "2"; 093 /** 送信状態 */ protected static final String SNED_NG = "8"; 094 095 /** GE30 カラム番号 {@value} */ 096 protected static final int GE30_UNIQ = 0 ; 097 private static final int GE30_PTN_ID = 1 ; 098 private static final int GE30_FROM_ID = 2 ; 099 private static final int GE30_TO_ID = 3 ; 100 private static final int GE30_CC_ID = 4 ; 101 private static final int GE30_BCC_ID = 5 ; 102 private static final int GE30_H_TXT = 6 ; // 5.0.3.0 (2009/11/04) HEADER ⇒ H_TXT 103 private static final int GE30_F_TXT = 7 ; // 5.0.3.0 (2009/11/04) FOOTER ⇒ F_TXT 104 private static final int GE30_PARAM0 = 8 ; 105 private static final int GE30_PARAM1 = 9 ; 106 private static final int GE30_PARAM2 = 10 ; 107 private static final int GE30_PARAM3 = 11 ; 108 private static final int GE30_PARAM4 = 12 ; 109 private static final int GE30_PARAM5 = 13 ; 110 private static final int GE30_PARAM6 = 14 ; 111 private static final int GE30_PARAM7 = 15 ; 112 private static final int GE30_PARAM8 = 16 ; 113 private static final int GE30_PARAM9 = 17 ; 114 private static final int GE30_ATTACH1 = 18 ; 115 private static final int GE30_ATTACH2 = 19 ; 116 private static final int GE30_ATTACH3 = 20 ; 117 private static final int GE30_ATTACH4 = 21 ; 118 private static final int GE30_ATTACH5 = 22 ; 119 120 /** GE36 カラム */ protected static final int GE36_PARA_KEY = 0 ; 121 /** GE36 カラム */ protected static final int GE36_ERRMSG = 1 ; 122 /** GE36 カラム */ protected static final int GE36_DYSET = 2 ; 123 /** GE36 カラム */ protected static final int GE36_USRSET = 3 ; 124 /** GE36 カラム */ protected static final int GE36_PGUPD = 4 ; 125 /** GE36 カラム */ protected static final int GE36_SYSTEM_ID = 5 ; 126 /** GE36 カラム */ protected final List<String> errMsgList = new ArrayList<>(); 127 128 /** 129 * デフォルトコンストラクター 130 * 131 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 132 */ 133 public MailManager_DB() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 134 135 /** 136 * バッチより呼出のメインメソッドです。 137 * パラメータテーブル(GE30)を監視します。 138 * 新規のデータが登録されたら、メール文を合成して送信を行います。 139 * エラーが発生した場合、エラーテーブルにエラーメッセージを書き込みます。 140 * 141 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 142 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 143 * @og.rev 5.9.18.0 (2017/03/02) SNDTIME対応 144 * 145 * @param systemId システムID 146 */ 147 public void sendDBMail( final String systemId ){ 148 // パラメータテーブルよりバッチでセットしたデータを取得します。 149 final String[][] ge30datas = DBUtil.dbExecute( SEL_GE30, new String[]{ systemId, DateSet.getDate( "yyyyMMddHHmmss" ) }, APP_INFO, DBID ); // 5.9.18.0 (2017/03/02) 150 151 final int ge30Len = ge30datas.length; 152 for( int i=0; i<ge30Len; i++ ) { 153 String fgj = SNED_OK; 154 try { 155 final ConcurrentMap<String, String> initParam = makeParamMap( systemId, ge30datas[i] ); 156 create( initParam ); 157 send(); // 合成されたメール文書、宛先で送信処理を行います。 158 errMsgList.addAll( getErrList() ); 159 } 160 catch( final RuntimeException rex ) { 161 fgj = SNED_NG; 162 errMsgList.add( "メール送信失敗しました。パラメータキー:" + ge30datas[i][GE30_UNIQ] + " " + rex.getMessage() ); 163 } 164 finally { 165 commitParamTable( ge30datas[i][GE30_UNIQ], fgj ); 166 if( ! errMsgList.isEmpty() ) { 167 writeErrorTable( ge30datas[i][GE30_UNIQ], systemId, errMsgList ); 168 errMsgList.clear(); 169 } 170 } 171 } 172 } 173 174 /** 175 * パラメータテーブルに登録したデータをパラメータマップにセットします。 176 * 177 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。 178 * @og.rev 6.4.3.3 (2016/03/04) ConcurrentHashMap を受け取ることを明確にするため、I/FをConcurrentMapに変更します。 179 * @og.rev 5.9.26.0 (2017/11/02) 子クラスでの利用対応。privateをprotectedに変更。 180 * 181 * @param systemId システムID 182 * @param ge30Data パラメータテーブルのデータ配列 183 * 184 * @return データをセットしたマップ 185 */ 186 protected ConcurrentMap<String, String> makeParamMap( final String systemId, final String[] ge30Data ){ // 6.4.3.3 (2016/03/04) ここは可変長はまずいでしょ。 187 ConcurrentMap<String,String> paramMap = null; 188 if( ge30Data != null && ge30Data.length > 0 ) { // 6.1.1.0 (2015/01/17) 可変長引数でもnullは来る。 189 paramMap = new ConcurrentHashMap<>(); 190 paramMap.put( "SYSTEM_ID" , systemId ); 191 paramMap.put( "PARAKEY" , ge30Data[GE30_UNIQ] ); 192 paramMap.put( "PTN_ID" , ge30Data[GE30_PTN_ID] ); 193 paramMap.put( "FROM" , ge30Data[GE30_FROM_ID] ); 194 paramMap.put( "TO" , ge30Data[GE30_TO_ID] ); 195 paramMap.put( "CC" , ge30Data[GE30_CC_ID] ); 196 paramMap.put( "BCC" , ge30Data[GE30_BCC_ID] ); 197 paramMap.put( "H_TXT" , ge30Data[GE30_H_TXT] ); // 5.0.3.0 (2009/11/04) HEADER ⇒ H_TXT 198 paramMap.put( "F_TXT" , ge30Data[GE30_F_TXT] ); // 5.0.3.0 (2009/11/04) FOOTER ⇒ F_TXT 199 paramMap.put( "PARAM0" , ge30Data[GE30_PARAM0] ); 200 paramMap.put( "PARAM1" , ge30Data[GE30_PARAM1] ); 201 paramMap.put( "PARAM2" , ge30Data[GE30_PARAM2] ); 202 paramMap.put( "PARAM3" , ge30Data[GE30_PARAM3] ); 203 paramMap.put( "PARAM4" , ge30Data[GE30_PARAM4] ); 204 paramMap.put( "PARAM5" , ge30Data[GE30_PARAM5] ); 205 paramMap.put( "PARAM6" , ge30Data[GE30_PARAM6] ); 206 paramMap.put( "PARAM7" , ge30Data[GE30_PARAM7] ); 207 paramMap.put( "PARAM8" , ge30Data[GE30_PARAM8] ); 208 paramMap.put( "PARAM9" , ge30Data[GE30_PARAM9] ); 209 paramMap.put( "ATTACH1" , ge30Data[GE30_ATTACH1] ); 210 paramMap.put( "ATTACH2" , ge30Data[GE30_ATTACH2] ); 211 paramMap.put( "ATTACH3" , ge30Data[GE30_ATTACH3] ); 212 paramMap.put( "ATTACH4" , ge30Data[GE30_ATTACH4] ); 213 paramMap.put( "ATTACH5" , ge30Data[GE30_ATTACH5] ); 214 paramMap.put( "DATE" , DateSet.getDate("yyyy/MM/dd") ); // 6.4.2.0 (2016/01/29) 215 paramMap.put( "TIME" , DateSet.getDate("HH:mm:ss") ); // 6.4.2.0 (2016/01/29) 216 paramMap.put( "LOGIN_USERID", "DAEMON" ); 217 paramMap.put( "LOGIN_USERNAME", "DAEMON" ); 218 paramMap.put( "PGID", "DAEMON" ); 219 } 220 return paramMap; 221 } 222 223 /** 224 * 送信後、パラメータテーブルの状況フラグを更新します。 225 * 送信エラーなしの場合はフラグを’送信済(2)’、エラーの場合’送信エラー(8)’に更新します。 226 * 227 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 228 * @og.rev 5.9.26.0 (2017/11/02) 子クラスでの利用対応。privateをprotectedに変更。 229 * 230 * @param uniq ユニークキー 231 * @param fgj 状況フラグ[2:送信済/8:エラー] 232 */ 233 protected void commitParamTable( final String uniq, final String fgj ){ 234 final String[] updGE30Args = { fgj, uniq }; 235 DBUtil.dbExecute( UPD_GE30, updGE30Args, APP_INFO, DBID ); // 5.5.5.1 (2012/08/07) 236 } 237 238 /** 239 * エラーテーブルにエラーメッセージを登録します。 240 * 241 * @og.rev 4.4.0.1 (2009/08/08) メール送信追加 242 * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対策 243 * @og.rev 6.4.2.0 (2016/01/29) DateSet.getDate( String ) を利用するように修正します。 244 * 245 * @param paraKey パラメータキー(GE36.PARA_KEY) 246 * @param systemId システムID 247 * @param emList エラーメッセージリスト 248 * 249 */ 250 private void writeErrorTable( final String paraKey, final String systemId, final List<String> emList ){ 251 final String[] insGE36Args = new String[6]; // 8.5.4.2 (2024/01/12) PMD 7.0.0 LocalVariableCouldBeFinal 252 insGE36Args[GE36_PARA_KEY] = paraKey; 253 insGE36Args[GE36_DYSET] = DateSet.getDate( "yyyyMMddHHmmss" ); // 6.4.2.0 (2016/01/29) 254 insGE36Args[GE36_USRSET] = "DAEMON"; 255 insGE36Args[GE36_PGUPD] = "DAEMON"; 256 insGE36Args[GE36_SYSTEM_ID] = systemId; 257 // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach 258// for( int i=0; i< emList.size(); i++ ){ 259// insGE36Args[GE36_ERRMSG] = trim( emList.get( i ), 4000); 260 for( final String errMsg : emList ){ 261 insGE36Args[GE36_ERRMSG] = trim( errMsg, 4000); 262 DBUtil.dbExecute( INS_GE36, insGE36Args, APP_INFO, DBID ); // 5.5.5.1 (2012/08/07) 263 } 264 265 sendMail( paraKey, systemId, emList ); // 4.4.0.1 (2009/08/08) 266 } 267 268 /** 269 * エラー情報のメール送信を行います。 270 * エラーメールは、システムパラメータ の COMMON_MAIL_SERVER(メールサーバー)と 271 * ERROR_MAIL_FROM_USER(エラーメール発信元)と、ERROR_MAIL_TO_USERS(エラーメール受信者) 272 * がすべて設定されている場合に、送信されます。 273 * 274 * @og.rev 4.4.0.1 (2009/08/08) 追加 275 * @og.rev 5.4.3.2 (2012/01/06) 認証対応 276 * @og.rev 6.0.3.0 (2014/11/13) Ver6用キーワード変更 277 * @og.rev 6.3.8.0 (2015/09/11) SSL接続するかどうかを指定するパラメータを追加します。 278 * @og.rev 6.3.8.0 (2015/09/11) SSL接続するかどうかを指定するパラメータを追加します。 279 * @og.rev 5.9.29.2 (2018/02/16) STARTTLS対応(キーワードをVer5 にあわせます) 280 * 281 * @param paraKey メールキー 282 * @param systemId システムID 283 * @param emList エラーメッセージリスト 284 */ 285 private void sendMail( final String paraKey, final String systemId, final List<String> emList ) { 286 287 final String host = HybsSystem.sys( "COMMON_MAIL_SERVER" ); 288 final String from = HybsSystem.sys( "ERROR_MAIL_FROM_USER" ); 289 final String charset = HybsSystem.sys( "MAIL_DEFAULT_CHARSET" ); 290 final String smtpPort = HybsSystem.sys( "SMTP_PORT" ); // 5.4.3.2 (2012/01/06) 291 final String authType = HybsSystem.sys( "MAIL_SEND_AUTH" ); // 6.0.3.0 (2014/11/13) Ver6用キーワード変更 292 final String authPort = HybsSystem.sys( "MAIL_SEND_AUTH_PORT" ); // 5.8.1.1 (2014/11/14) 293 final String authUser = HybsSystem.sys( "MAIL_SEND_AUTH_USER" ); // 5.4.3.2 (2012/01/06) 294 final String authPass = HybsSystem.sys( "MAIL_SEND_AUTH_PASSWORD" ); // 5.4.3.2 (2012/01/06) 295 final boolean useSSL = HybsSystem.sysBool( "MAIL_SEND_USE_SSL" ); // 6.3.8.0 (2015/09/11) 296 final boolean useTLS = HybsSystem.sysBool( "MAIL_SEND_USE_STARTTLS" ); // 5.9.29.2(2018/02/16) 297 298 final String[] to = StringUtil.csv2Array( HybsSystem.sys( "ERROR_MAIL_TO_USERS" ) ); 299 if( host != null && from != null && to.length > 0 ) { 300 final String subject = "SYSTEM_ID=[" + systemId + "] , PARA_KEY=[" + paraKey + "] , " 301 + "DMN_HOST=[" + HybsSystem.HOST_NAME + "]" ; 302 final StringBuilder inErrMsg = new StringBuilder( BUFFER_MIDDLE ) 303 .append( emList.size() ).append( "件のエラーがありました。" ) // 6.0.2.5 (2014/10/31) char を append する。 304 .append( CR ); 305 for( int i=0; i< emList.size(); i++ ){ 306 inErrMsg.append( i+1 ) 307 .append( "-----" ) 308 .append( CR ) 309 .append( emList.get( i ) ) 310 .append( CR ); 311 } 312 try { 313 //MailTX tx = new MailTX( host ); 314// final MailTX tx = new MailTX( host, charset, smtpPort, authType, authPort, authUser, authPass, useSSL ); // 6.3.8.0 (2015/09/11) 315 final MailTX tx = new MailTX( host, charset, smtpPort, authType, authPort, authUser, authPass, useTLS, useSSL ); // 5.9.29.2 316 tx.setFrom( from ); 317 tx.setTo( to ); 318 tx.setSubject( "メールモジュール送信エラー:" + subject ); 319 tx.setMessage( inErrMsg.toString() ); 320 tx.sendmail(); 321 } 322 catch( final Throwable ex ) { 323 final String errMsg = "エラー時メール送信に失敗しました。" + CR 324 + " SUBJECT:" + subject + CR 325 + " HOST:" + host + CR 326 + " FROM:" + from + CR 327 + " TO:" + Arrays.toString( to ) + CR 328 + ex.getMessage(); // 5.1.8.0 (2010/07/01) errMsg 修正 329 LogWriter.log( errMsg ); 330 LogWriter.log( ex ); 331 } 332 } 333 } 334}