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