001package com.poscoict.app.job;
002
003import java.io.IOException;
004import java.net.InetAddress;
005import java.net.UnknownHostException;
006import java.util.ArrayList;
007
008import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
009import org.apache.commons.httpclient.HttpClient;
010import org.apache.commons.httpclient.HttpException;
011import org.apache.commons.httpclient.NameValuePair;
012import org.apache.commons.httpclient.methods.PostMethod;
013import org.apache.commons.httpclient.params.HttpMethodParams;
014import org.slf4j.Logger;
015import org.slf4j.LoggerFactory;
016
017import com.poscoict.glueframework.GlueException;
018
019/**
020 * Job 실행여부 확인 Util.
021 * 
022 * <pre>
023 * 사용예#1
024 * <xmp>
025 * String JobKey = ... ;//sample1.job001
026 * GlueJobDefinition jobDefinition = ...; //new GlueJobDefinition( "-1", JobKey );
027 * String serverAddress = ...; //http://192.168.41.141:8805
028 * GlueJobEventSender sender = ...;// GlueStaticContext.getBeanFactory().getBeanObject( "jobEventSender", GlueJobEventSender.class );
029 * String historyId = sender.sendJobEvent( def, serverAddress + "/scheduler" );
030 * 
031 * String status = GlueJobStatusCheck.getJobStatus(serverAddress, historyId, JobKey );
032 * </xmp>
033 * 
034 * 
035 * 사용예#2
036 * <xmp>
037 * String JobKey = ... ;//sample1.job001
038 * String serverAddress = ...; //http://192.168.41.141:8805
039 * String ids = GlueJobStatusCheck.getJobHistoryIdsByJobKey(serverAddress, JobKey );
040 * String[] historyIds = ids.split( "," );
041 * for( String historyId : historyIds ){
042 *     String status = GlueJobStatusCheck.getJobStatus(serverAddress, historyId, JobKey );
043 * }
044 * </xmp>
045 * </pre>
046 * 
047 * @see org.apache.commons.httpclient.HttpClient
048 * @see org.apache.commons.httpclient.methods.PostMethod
049 */
050public abstract class GlueJobStatusCheck
051{
052    private static Logger logger = LoggerFactory.getLogger( GlueJobStatusCheck.class );
053
054    /**
055     * @param url GlueJobScheduler Server 주소. 내부적으로 HttpClient 를 통해 PostMethod 실행 URL임
056     * @param requestId Job History ID. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
057     * @param jobKey JobKey. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨. requestId 가 유효한지 체크하는데 사용됨.
058     * @return COMPLETE,STOPPED,ERROR,MISFIRED,RUNNING 등의 STATUS 값.
059     */
060    public static String getJobStatus( String url, String requestId, String jobKey )
061    {
062        String ip = null;
063        try
064        {
065            InetAddress localMachine = InetAddress.getLocalHost();
066            ip = localMachine.getHostAddress();
067            return getJobStatus( url, requestId, jobKey, ip, 2 );
068        } catch ( UnknownHostException e )
069        {
070            logger.error( "UnknownHostException", e );
071            return null;
072        }
073    }
074
075    /**
076     * @param url GlueJobScheduler Server 주소. 내부적으로 HttpClient 를 통해 PostMethod 실행 URL임.
077     * @param requestId Job History ID. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
078     * @param jobKey JobKey. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨. requestId 가 유효한지 체크하는데 사용됨.
079     * @param ip LocalHost 주소. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
080     * @return COMPLETE,STOPPED,ERROR,MISFIRED,RUNNING 등의 STATUS 값.
081     */
082    public static String getJobStatus( String url, String requestId, String jobKey, String ip )
083    {
084        return getJobStatus( url, requestId, jobKey, ip, 2 );
085    }
086
087    /**
088     * @param url GlueJobScheduler Server 주소. 내부적으로 HttpClient 를 통해 PostMethod 실행 URL임.
089     * @param requestId Job History ID. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
090     * @param jobKey JobKey. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨. requestId 가 유효한지 체크하는데 사용됨.
091     * @param ip LocalHost 주소. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
092     * @param retryCount HttpClient 를 통해 PostMethod 실행 실패시 재시도 횟수임.
093     * @return COMPLETE,STOPPED,ERROR,MISFIRED,RUNNING 등의 STATUS 값.
094     */
095    public static String getJobStatus( String url, String requestId, String jobKey, String ip, int retryCount )
096    {
097        HttpClient client = new HttpClient();
098        PostMethod method = new PostMethod( url );
099        // header 설정
100        method.addRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" );
101        // encoding
102
103        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
104        // Request ID, Job Name, Client IP 설정
105        nameValuePairs.add( new NameValuePair( "check", "status" ) );
106        nameValuePairs.add( new NameValuePair( GlueSchedulerConstants.REQUEST_ID, requestId ) );
107        nameValuePairs.add( new NameValuePair( "jobKey", jobKey ) );
108        nameValuePairs.add( new NameValuePair( GlueSchedulerConstants.CLIENT_IP, ip ) );
109        // prepare parameters for post
110        NameValuePair[] nvps = new NameValuePair[nameValuePairs.size()];
111        nvps = nameValuePairs.toArray( nvps );
112        method.setRequestBody( nvps );
113
114        // provide custom retry handler is necessary
115        // Request 전송 실패 시 2번 더 시도를 한다.
116        method.getParams().setParameter( HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler( retryCount, false ) );
117        String responseBody = null;
118        try
119        {
120            // execute the method
121            int statusCode = client.executeMethod( method );
122            if ( statusCode != GlueSchedulerConstants.STATUS_JOB_SUCCESS
123                    && statusCode != GlueSchedulerConstants.HTTP_STATUS_SUCCESS )
124            {
125                logger.error( "Method failed: {}", method.getStatusLine() );
126            }
127
128            // read the response body
129            responseBody = new String( method.getResponseBody() );
130
131            // deal with response
132            // use caution: ensure correct character encoding
133            // is not binary data
134            logger.info( "Response Body :{}", responseBody );
135            logger.info( "Status Line :{}", method.getStatusLine() );
136        } catch ( HttpException httpe )
137        {
138            throw new GlueException( "Fatal protocol violation: " + httpe.getMessage(), httpe );
139        } catch ( IOException ioe )
140        {
141            throw new GlueException( "Fatal transport error: " + ioe.getMessage(), ioe );
142        } finally
143        {
144            // release the connection
145            method.releaseConnection();
146        }
147        return responseBody;
148    }
149
150    /**
151     * @param url GlueJobScheduler Server 주소. 내부적으로 HttpClient 를 통해 PostMethod 실행 URL임.
152     * @param jobKey JobKey. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
153     * @return 실행중이거나 대기중인 Job Histroy ID. 2개 이상일경우 컴마(,)로 구분함.
154     */
155    public static String getJobHistoryIdsByJobKey( String url, String jobKey )
156    {
157        String ip = null;
158        try
159        {
160            InetAddress localMachine = InetAddress.getLocalHost();
161            ip = localMachine.getHostAddress();
162            return getJobHistoryIdsByJobKey( url, jobKey, ip, 2 );
163        } catch ( UnknownHostException e )
164        {
165            logger.error( "UnknownHostException", e );
166            return null;
167        }
168
169    }
170
171    /**
172     * @param url GlueJobScheduler Server 주소. 내부적으로 HttpClient 를 통해 PostMethod 실행 URL임.
173     * @param jobKey JobKey. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
174     * @param ip LocalHost 주소. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
175     * @return 실행중이거나 대기중인 Job Histroy ID. 2개 이상일경우 컴마(,)로 구분함.
176     */
177    public static String getJobHistoryIdsByJobKey( String url, String jobKey, String ip )
178    {
179        return getJobHistoryIdsByJobKey( url, jobKey, ip, 2 );
180    }
181
182    /**
183     * @param url GlueJobScheduler Server 주소. 내부적으로 HttpClient 를 통해 PostMethod 실행 URL임.
184     * @param jobKey JobKey. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
185     * @param ip LocalHost 주소. 내부적으로 NameValuePair 으로 생성되서 setRequestBody()로 전달됨.
186     * @param retryCount HttpClient 를 통해 PostMethod 실행 실패시 재시도 횟수임.
187     * @return 실행중이거나 대기중인 Job Histroy ID. 2개 이상일경우 컴마(,)로 구분함.
188     */
189    public static String getJobHistoryIdsByJobKey( String url, String jobKey, String ip, int retryCount )
190    {
191        HttpClient client = new HttpClient();
192        PostMethod method = new PostMethod( url );
193        // header 설정
194        method.addRequestHeader( "Content-Type", "application/x-www-form-urlencoded; charset=UTF-8" );
195        // encoding
196
197        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
198        // Request ID, Job Name, Client IP 설정
199        nameValuePairs.add( new NameValuePair( "check", "status" ) );
200        nameValuePairs.add( new NameValuePair( "jobKey", jobKey ) );
201        nameValuePairs.add( new NameValuePair( GlueSchedulerConstants.CLIENT_IP, ip ) );
202        // prepare parameters for post
203        NameValuePair[] nvps = new NameValuePair[nameValuePairs.size()];
204        nvps = nameValuePairs.toArray( nvps );
205        method.setRequestBody( nvps );
206
207        // provide custom retry handler is necessary
208        // Request 전송 실패 시 2번 더 시도를 한다.
209        method.getParams().setParameter( HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler( retryCount, false ) );
210        String responseBody = null;
211        try
212        {
213            // execute the method
214            int statusCode = client.executeMethod( method );
215            if ( statusCode != GlueSchedulerConstants.STATUS_JOB_SUCCESS
216                    && statusCode != GlueSchedulerConstants.HTTP_STATUS_SUCCESS )
217            {
218                logger.error( "Method failed: {}", method.getStatusLine() );
219            }
220
221            // read the response body
222            responseBody = new String( method.getResponseBody() );
223
224            // deal with response
225            // use caution: ensure correct character encoding
226            // is not binary data
227            logger.info( "Response Body :{}", responseBody );
228            logger.info( "Status Line :{}", method.getStatusLine() );
229        } catch ( HttpException httpe )
230        {
231            throw new GlueException( "Fatal protocol violation: " + httpe.getMessage(), httpe );
232        } catch ( IOException ioe )
233        {
234            throw new GlueException( "Fatal transport error: " + ioe.getMessage(), ioe );
235        } finally
236        {
237            // release the connection
238            method.releaseConnection();
239        }
240        return responseBody;
241    }
242}