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     */
016    package org.opengion.plugin.daemon;
017    
018    import java.util.Arrays;
019    import java.util.Date;
020    import java.util.LinkedHashMap;
021    import java.util.LinkedHashSet;
022    import java.util.Map;
023    import java.util.Set;
024    
025    import org.opengion.fukurou.db.DBUtil;
026    import org.opengion.fukurou.mail.MailTX;
027    import org.opengion.fukurou.transfer.TransferConfig;
028    import org.opengion.fukurou.transfer.TransferProcess;
029    import org.opengion.fukurou.util.ApplicationInfo;
030    import org.opengion.fukurou.util.HybsTimerTask;
031    import org.opengion.fukurou.util.LogWriter;
032    import org.opengion.fukurou.util.StringUtil;
033    import org.opengion.hayabusa.common.HybsSystem;
034    import org.opengion.hayabusa.common.HybsSystemException;
035    
036    /**
037     * 【伝é?シスãƒ?ƒ 】各読取方法ã?実行方法に応じて伝é?処ç�?‚’行うためのãƒ??モンですã?
038     *
039     * 読取ã?及ã?実行におけるå?体的な処ç�?�«つã�?�¦は、{@link org.opengion.fukurou.transfer}パッケージå†??
040     * å�?®Ÿè£?‚¯ラスのドキュメントを参ç?して下さã�??
041     *
042     * なおã?å�??ç�??実行につã�?�¦、トランザクションは、読取対象の単位になりますã?
043     * 同じ読取対象で、異なる実行方法ã?実行対象を定義した場合ã?同じãƒ??タに対してè¤?•°回å?ç�?�Œ行われますã?
044     * しかしã?こã?場合においてもã?トランザクションは読取対象の単位で生æ?されるためã?è¤?•°回ã?処ç�??å†??
045     * 1回でもエラーが発生したå?合ã?、同じ読取対象でそれまでに処ç�?�—たå?につã�?�¦もrollbackされますã?
046     *
047     * 発生したエラーをメールで通知する場合ã?以下ã?設定を行うå¿?¦�がありますã?
048     * [シスãƒ?ƒ リソース]
049     *  COMMON_MAIL_SERVER
050     *  ERROR_MAIL_FROM_USER
051     * [伝é?定義マスタ]
052     *  エラー送信å…?
053     * ※伝é?定義マスタ読取時にエラーが発生したå?合ã?、シスãƒ?ƒ リソースの"ERROR_MAIL_TO_USERS"で
054     *   設定さえたユーザーにメールがé?信されますã?
055     *
056     * ※処ç�?¸­に何らかã?エラーã�?度でも発生したå?合ã?こã?ãƒ??モンは停止しますã?
057     *
058     * こã?クラスは、HybsTimerTask を継承した タイマã?タスククラスですã?
059     * startDaemon() がタイマã?タスクによって、呼び出されますã?
060     *
061     * @og.rev 5.4.1.0 (2011/11/01) 伝é?シスãƒ?ƒ 対å¿?
062     * @og.group ãƒ??モン
063     *
064     * @version  5.0
065     * @author   Hiroki Nakamura
066     * @since    JDK6.0,
067     */
068    public class Daemon_Transfer extends HybsTimerTask {
069            //* こã?プログラãƒ??VERSIONæ–?­—å?を設定しますã?       {@value} */
070            private static final String VERSION = "5.5.5.1 (2012/08/07)" ;
071    
072            // 伝é?定義マスタ検索用SQL
073            private static final String GE62_SELECT =
074                    "SELECT A.KBREAD,A.READOBJ,A.READPRM,A.KBEXEC,A.EXECDBID,A.EXECOBJ,A.EXECPRM,A.ERROR_SENDTO" +
075                    " FROM GE62 A" +
076                    " WHERE A.FGJ = '1'";
077    
078            // コネクションにアプリケーションæƒ??を追記するかどã�?�‹æŒ?®?
079            private static final boolean USE_DB_APPLICATION_INFO  = HybsSystem.sysBool( "USE_DB_APPLICATION_INFO" ) ;
080    
081            // HTTP接続時のプロキシホスãƒ?
082            private static final String HTTP_PROXY_HOST = HybsSystem.sys( "HTTP_PROXY_HOST" );
083    
084            // HTTP接続時のプロキシポã?ãƒ?
085            private static final int HTTP_PROXY_PORT = HybsSystem.sysInt( "HTTP_PROXY_PORT" );
086    
087            // 呼び出しå?ホストコーãƒ?
088            private static final String HFROM = HybsSystem.sys( "TRANSFER_HOST_CODE" );
089    
090            // ループカウンタã‚?4回に設å®?
091            private static final int LOOP_COUNTER = 24;
092    
093            private boolean running = true;
094            private int loopCnt             = 0;
095    
096            private String ge62Select = null;
097            private String dmnName = null;
098    
099            private ApplicationInfo appInfo = null;
100            private boolean debug = false;
101    
102            protected final String DBID = HybsSystem.sys( "RESOURCE_DBID" );                // 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対å¿?
103    
104            /**
105             * こã?タイマã?タスクによって初期化されるアクションですã?
106             * パラメータを使用した初期化を行いますã?
107             *
108             */
109            @Override
110            public void initDaemon() {
111                    debug = StringUtil.nval( getValue( "DEBUG" ),debug );
112    
113                    dmnName = getName();
114    
115                    StringBuilder buf = new StringBuilder();
116                    buf.append( GE62_SELECT );
117    
118                    // シスãƒ?ƒ IDはå¿??æŒ?®?
119                    String systemId = getValue( "SYSTEM_ID" );
120                    if( StringUtil.isNull( systemId ) ) {
121                            String errMsg = "シスãƒ?ƒ ID方法ã?å¿??æŒ?®šですã?" ;
122                            throw new HybsSystemException( errMsg );
123                    }
124                    else {
125                            buf.append( " AND A.SYSTEM_ID='" ).append( systemId ).append( "'" );
126                    }
127    
128                    // 読取方法ã?å¿??æŒ?®?
129                    String kbRead = getValue( "KBREAD" );
130                    if( StringUtil.isNull( kbRead ) ) {
131                            String errMsg = "読取方法ã?å¿??æŒ?®šですã?" ;
132                            throw new HybsSystemException( errMsg );
133                    }
134                    else {
135                            buf.append( " AND A.KBREAD='" ).append( kbRead ).append( "'" );
136                    }
137    
138                    // ãƒ??モングループã?å¿??æŒ?®?
139                    String dmnGroup = getValue( "DMN_GRP" );
140                    if( StringUtil.isNull( dmnGroup ) ) {
141                            String errMsg = "ãƒ??モングループã?å¿??æŒ?®šですã?" ;
142                            throw new HybsSystemException( errMsg );
143                    }
144                    else {
145                            buf.append( " AND A.DMN_GRP='" ).append( dmnGroup ).append( "'" );
146                    }
147    
148                    buf.append( " ORDER BY A.READOBJ,A.KBEXEC,A.EXECOBJ" );
149    
150                    ge62Select = buf.toString() ;
151    
152                    if( debug ) {
153                            System.out.println( "DMN_NAME=[" + dmnName + "]" );
154                            System.out.println( "QUERY=[" + ge62Select + "]" );
155                    }
156    
157                    if( USE_DB_APPLICATION_INFO ) {
158                            appInfo = new ApplicationInfo();
159                            // ユーザーID,IPアドレス,ホスト名
160                            appInfo.setClientInfo( systemId,HybsSystem.HOST_ADRS,HybsSystem.HOST_NAME );
161                            // 画面ID,操ä½?プログラãƒ?D
162                            appInfo.setModuleInfo( "TransferDaemon",dmnName,dmnName );
163                    }
164                    else {
165                            appInfo = null;
166                    }
167            }
168    
169            /**
170             * タイマã?タスクのãƒ??モン処ç�??開始ã?イントですã?
171             *
172             * @og.rev 5.5.5.1 (2012/08/07) リソース系DBID 付け忘れ対ç­?
173             */
174            @Override
175            protected void startDaemon() {
176                    if( loopCnt % LOOP_COUNTER == 0 ) {
177                            loopCnt = 1;
178                            System.out.println();
179                            System.out.print( toString() + " " + new Date()  + " " );
180                    }
181                    else {
182                            System.out.print( "." );
183                            loopCnt++ ;
184                    }
185    
186                    // 伝é?DB読å�?
187                    String[][] vals  = null;
188                    GE62Data ge62Data = new GE62Data();
189                    try {
190    //                      vals = DBUtil.dbExecute( ge62Select,null,appInfo );
191                            vals = DBUtil.dbExecute( ge62Select,null,appInfo,DBID );                // 5.5.5.1 (2012/08/07)
192                            if( vals != null && vals.length > 0 ) {
193                                    for( int row=0; running && row<vals.length; row++ ) {
194                                            ge62Data.addData( vals[row] );
195                                    }
196                            }
197                    }
198                    catch( Throwable ex ) {
199                            String header = "伝é?読取エラー?šDMN_NAME=[" + dmnName + "] , DMN_HOST=[" + HybsSystem.HOST_NAME + "] , QUERY=[" + ge62Select + "]";
200                            String errMsg = header + HybsSystem.CR + StringUtil.stringStackTrace( ex ) ;
201                            System.out.println( errMsg );
202                            LogWriter.log( errMsg );
203                            String errorSendto = HybsSystem.sys( "ERROR_MAIL_TO_USERS" );
204                            sendMail( header, errMsg, errorSendto );
205                    }
206    
207                    // 処ç�?®Ÿè¡?
208                    // 読取対象の単位で処ç�?‚’実行しますã?(トランザクションもこの単位になりまã�?
209                    for( String tranKey : ge62Data.getTranSet() ) {
210                            TransferProcess proc = null;
211                            try {
212                                    proc = new TransferProcess( ge62Data.getConfSet( tranKey ) );
213                                    proc.setDmnName( dmnName );
214                                    proc.setAppInfo( appInfo );
215                                    if( debug ) {
216                                            proc.setDebug();
217                                    }
218    
219                                    proc.process();
220                            }
221                            catch( Throwable ex ) {
222                                    // エラーが発生したå?合ã?ãƒ??モンを停止しますã?
223                                    cancel();
224    
225                                    // æœ?¾Œに処ç�?�—た伝é?設定オブジェクトを下にエラーをå?力しますã?
226                                    String header = "伝é?エラー?šDMN_NAME=[" + dmnName + "] , DMN_HOST=[" + HybsSystem.HOST_NAME + "]";
227                                    String errorSendto = null;
228                                    if( proc != null ) {                            // 5.5.2.6 (2012/05/25) findbugs対å¿?
229                                            TransferConfig config = proc.getLastConfig();
230                                            if( config != null ) {
231                                                    header += " , CONFIG=[" + config.toString() + "]";
232                                                    errorSendto = config.getErrorSendto();
233                                            }
234                                    }
235    
236                                    String errMsg = header + HybsSystem.CR + StringUtil.stringStackTrace( ex ) ;
237                                    System.out.println( errMsg );
238                                    LogWriter.log( errMsg );
239                                    sendMail( header, errMsg, errorSendto );
240                            }
241                    }
242            }
243    
244            /**
245             * こã?タイマã?タスクのcancel() メソãƒ?ƒ‰をオーバã?ライドしますã?
246             * HybsTimerTaskManager#cancelTask( int ) を実行しますã?
247             *
248             * @return      スケジュールされてã�?‚‹ 1 回以上実行されなã�??合に true
249             * @see java.util.TimerTask#cancel()
250             */
251            @Override
252            public boolean cancel() {
253                    running = false;
254                    return super.cancel();
255            }
256    
257            /**
258             * エラーæƒ??のメール送信を行いますã?
259             * エラーメールは、シスãƒ?ƒ パラメータ の COMMON_MAIL_SERVER(メールサーバã?)と
260             * ERROR_MAIL_FROM_USER(エラーメール発信å…?と、ERROR_MAIL_TO_USERS(エラーメール受信è€?
261             * がすべて設定されてã�?‚‹場合にã€??信されますã?
262             *
263             * @param       inHeader        ヘッãƒ??メãƒ?‚»ージ
264             * @param       inErrMsg        エラーメãƒ?‚»ージ
265             * @param       errorSendto     エラー送信å…?
266             */
267            protected void sendMail( final String inHeader, final String inErrMsg, final String errorSendto ) {
268    
269                    String   host = HybsSystem.sys( "COMMON_MAIL_SERVER" );
270                    String   from = HybsSystem.sys( "ERROR_MAIL_FROM_USER" );
271    //              String[] to = StringUtil.csv2Array( HybsSystem.sys( "ERROR_MAIL_TO_USERS" ) );
272                    String[] to = StringUtil.csv2Array( errorSendto );
273    
274                    if( host != null && from != null && to.length > 0 ) {
275                            try {
276                                    MailTX tx = new MailTX( host );
277                                    tx.setFrom( from );
278                                    tx.setTo( to );
279                                    tx.setSubject( inHeader );
280                                    tx.setMessage( inErrMsg );
281                                    tx.sendmail();
282                            }
283                            catch( Throwable ex ) {
284                                    String errMsg = "エラー時メール送信に失敗しましたã€? + HybsSystem.CR
285                                                            + " SUBJECT:" + inHeader                                + HybsSystem.CR
286                                                            + " HOST:" + host                                               + HybsSystem.CR
287                                                            + " FROM:" + from                                               + HybsSystem.CR
288                                                            + " TO:"   + Arrays.toString( to )              + HybsSystem.CR
289                                                            + ex.getMessage();
290                                    LogWriter.log( errMsg );
291                                    LogWriter.log( ex );
292                            }
293                    }
294            }
295    
296            /**
297             * 伝é?定義マスタから読み出したãƒ??タを管ç�?�—ますã?
298             */
299            private static class GE62Data {
300    
301                    // トランザクションを生成するキーのセãƒ?ƒˆ(読取対象単ä½?
302                    private final Set<String> tranSet = new LinkedHashSet<String>();
303                    // トランザクションキー(読取対象)に対する、設定オブジェクトã?セãƒ?ƒˆ
304                    private final Map<String,Set<TransferConfig>> tran2ConfSet = new LinkedHashMap<String,Set<TransferConfig>>();
305    
306                    /**
307                     * GE62読取データを追åŠ?�—ますã?
308                     *
309                     * @param data GE62読取データ
310                     */
311                    private void addData( final String[] data ) {
312                            String kbRead           = data[0];
313                            String readObj          = data[1];
314                            String readPrm          = data[2];
315                            String kbExec           = data[3];
316                            String execDbid         = data[4];
317                            String execObj          = data[5];
318                            String execPrm          = data[6];
319                            String errorSendto      = data[7];
320    
321                            String tranKey = readObj;
322                            tranSet.add( tranKey );
323    
324                            Set<TransferConfig> confSet = tran2ConfSet.get( tranKey );
325                            if( confSet == null ) {
326                                    confSet = new LinkedHashSet<TransferConfig>();
327                            }
328                            TransferConfig conf = new TransferConfig(
329                                                                                    kbRead, readObj, readPrm
330                                                                                    , kbExec, execDbid, execObj, execPrm
331                                                                                    , errorSendto, HFROM, HTTP_PROXY_HOST, HTTP_PROXY_PORT );
332                            confSet.add( conf );
333                            tran2ConfSet.put( tranKey, confSet );
334                    }
335    
336                    /**
337                     * トランザクション生æ?キー(読取対象)のセãƒ?ƒˆを返しますã?
338                     *
339                     * @return トランザクション生æ?キー(読取対象)のセãƒ?ƒˆ
340                     */
341                    private Set<String> getTranSet() {
342                            return tranSet;
343                    }
344    
345                    /**
346                     * トランザクション生æ?キー(読取対象)に対する設定オブジェクトã?セãƒ?ƒˆを返しますã?
347                     *
348                     * @param tranKey トランザクション生æ?キー(読取対象)
349                     * @return 設定オブジェクトã?セãƒ?ƒˆ
350                     */
351                    private Set<TransferConfig> getConfSet( final String tranKey ) {
352                            return tran2ConfSet.get( tranKey );
353                    }
354            }
355    }