001 // Copyright(c) 2015 POSCO ICT
002 // Change history
003 // 2015-07-10 / 1.1.0 /
004 package com.poscoict.app.job;
005
006 import java.lang.management.ManagementFactory;
007 import java.lang.reflect.InvocationTargetException;
008 import java.lang.reflect.Method;
009 import java.sql.Connection;
010 import java.sql.PreparedStatement;
011 import java.sql.SQLException;
012 import java.util.Date;
013 import java.util.List;
014 import java.util.Map;
015
016 import javax.sql.DataSource;
017
018 import org.apache.commons.dbcp.BasicDataSource;
019 import org.slf4j.Logger;
020 import org.slf4j.LoggerFactory;
021 import org.springframework.context.ApplicationContext;
022 import org.springframework.context.support.ClassPathXmlApplicationContext;
023 import org.springframework.jdbc.datasource.DataSourceUtils;
024 import org.springframework.jdbc.support.JdbcUtils;
025
026 import com.poscoict.glueframework.biz.control.GlueBizControlConstants;
027 import com.poscoict.glueframework.biz.control.GlueBizProvider;
028 import com.poscoict.glueframework.context.GlueContext;
029 import com.poscoict.glueframework.context.GlueDefaultContext;
030
031 /**
032 * Main Ŭ·¡½º.
033 *
034 * <pre>
035 * java [-option] com.poscoict.app.job.GlueSimpleJob [args..]
036 * ÇüÅ·ΠGlueSimpleJob Ŭ·¡½º¸¦ ½ÇÇàÇÑ´Ù.
037 *
038 * [args..] ºÎºÐÀÇ Ã¹¹øÂ°´Â history id, µÎ¹øÂ°´Â ½ÇÇàÀ¯Çü, ¼¼¹øÂ°ºÎÅÍ´Â »ç¿ëÀÚ data·Î ±¸¼ºÇÑ´Ù.
039 * <xmp>
040 * java [-option] com.poscoict.app.job.GlueSimpleJob -1 ServiceName=job001-service@S userKey=userData@S
041 * java [-option] com.poscoict.app.job.GlueSimpleJob -1 className=sample.job.SamplePgm@S userKey=userData@S
042 * </xmp>
043 * </pre>
044 */
045 public class GlueSimpleJob
046 {
047 static ApplicationContext applicationContext = null;
048 static Logger logger = LoggerFactory.getLogger( GlueSimpleJob.class );
049
050 public static void main( String args[] )
051 {
052 logger.info( "GlueSimpleJob version : {}", JobConstants.VERSION );
053 boolean isLocalTest = args != null && args.length > 0 && args[0] != null && "-1".equals( args[0] );
054 if ( !isLocalTest )
055 {
056 BasicDataSource dataSource = null;
057 Connection connection = null;
058 try
059 {
060 applicationContext = new ClassPathXmlApplicationContext( "applicationContext-job.xml" );
061 dataSource = applicationContext.getBean( "dataSource", BasicDataSource.class );
062 connection = DataSourceUtils.getConnection( dataSource );
063 String databaseProductName = connection.getMetaData().getDatabaseProductName().toLowerCase();
064 if ( databaseProductName.indexOf( "oracle" ) >= 0 )
065 {
066 dataSource.addConnectionProperty( "v$session.program", "GlueSimpleJob ver." + JobConstants.VERSION );
067 // dataSource.addConnectionProperty( "v$session.process", "GlueSimpleJob-java" );
068 // dataSource.addConnectionProperty( "v$session.terminal", "GlueSimpleJob-terminal" );
069 // dataSource.addConnectionProperty( "v$session.client_info", "GlueSimpleJob-client" );
070 } else if ( databaseProductName.indexOf( "postgresql" ) >= 0 || databaseProductName.indexOf( "enterprisedb" ) >= 0 )
071 {
072 dataSource.addConnectionProperty( "ApplicationName", "GlueSimpleJob ver." + JobConstants.VERSION );
073 } else
074 {
075 logger.warn( "not support - {}", databaseProductName );
076 }
077 if ( databaseProductName.indexOf( "oracle" ) >= 0 )
078 {
079 dataSource.addConnectionProperty( "v$session.program", "GlueSimpleJob ver." + JobConstants.VERSION );
080 }
081 } catch ( Throwable t )
082 {
083 logger.error( "Throwable", t );
084 t.printStackTrace();
085 return;
086 } finally
087 {
088 DataSourceUtils.releaseConnection( connection, dataSource );
089 }
090 }
091
092 String name = ManagementFactory.getRuntimeMXBean().getName();
093 String pid = name.substring( 0, name.indexOf( "@" ) );
094 logger.info( "RuntimeMXBean Name : {}, {}", name, pid );
095 if ( logger.isTraceEnabled() )
096 {
097 logger.trace( "BootClassPath : {}", ManagementFactory.getRuntimeMXBean().getBootClassPath() );
098 logger.trace( "ClassPath : {}", ManagementFactory.getRuntimeMXBean().getClassPath() );
099 logger.trace( "LibraryPath : {}", ManagementFactory.getRuntimeMXBean().getLibraryPath() );
100 logger.trace( "ManagementSpecVersion : {}", ManagementFactory.getRuntimeMXBean().getManagementSpecVersion() );
101 logger.trace( "SpecName : {}", ManagementFactory.getRuntimeMXBean().getSpecName() );
102 logger.trace( "SpecVendor : {}", ManagementFactory.getRuntimeMXBean().getSpecVendor() );
103 logger.trace( "SpecVersion : {}", ManagementFactory.getRuntimeMXBean().getSpecVersion() );
104 logger.trace( "StartTime : {}", ManagementFactory.getRuntimeMXBean().getStartTime() );
105 logger.trace( "Uptime : {}", ManagementFactory.getRuntimeMXBean().getUptime() );
106 logger.trace( "VmName : {}", ManagementFactory.getRuntimeMXBean().getVmName() );
107 logger.trace( "VmVendor : {}", ManagementFactory.getRuntimeMXBean().getVmVendor() );
108 logger.trace( "VmVersion : {}", ManagementFactory.getRuntimeMXBean().getVmVersion() );
109 logger.trace( "SystemProperties : {}", ManagementFactory.getRuntimeMXBean().getSystemProperties() );
110 logger.trace( "BootClassPathSupported : {}", ManagementFactory.getRuntimeMXBean().isBootClassPathSupported() );
111 logger.trace( "InputArguments : {}", ManagementFactory.getRuntimeMXBean().getInputArguments() );
112 List<String> arguements = ManagementFactory.getRuntimeMXBean().getInputArguments();
113 for ( String string : arguements )
114 {
115 logger.trace( "InputArgument : {}", string );
116 }
117 }
118 if ( !isLocalTest )
119 GlueSimpleJob.updateStartTime( args[0], pid );
120 long start = System.currentTimeMillis();
121 GlueContext ctx = new GlueDefaultContext();
122 String requestId = null;
123 try
124 {
125 requestId = args[0];
126 if ( logger.isTraceEnabled() )
127 {
128 Map<String, String> env = System.getenv();
129 logger.trace( "{}", env );
130 logger.trace( "" );
131 logger.trace( "{}", System.getProperties() );
132 logger.trace( "" );
133 logger.trace( "" );
134 }
135
136 logger.info( "RequestID:[{}] StartTime[{}]", requestId, new Date( start ) );
137
138 ctx.put( JobConstants.JOB_REQUEST_ID, requestId );
139
140 for ( int i = 1; i < args.length; i++ )
141 {
142 String arg = args[i];
143 logger.trace( "{}", arg );
144 // K:Keyword;S:String;B:boolean;I:Integer;L:Long;D:Double;F:Float
145 if ( arg.contains( "=" ) )
146 {
147 String s[] = arg.split( "=" );
148 if ( arg.startsWith( "\"" ) && arg.endsWith( "\"" ) )
149 {
150 String tmp = arg.substring( 1, arg.length() - 1 );
151 logger.trace( "{}", tmp );
152 s = tmp.split( "=" );
153 }
154 if ( s[1].contains( "@" ) )
155 {
156 int idx = s[1].lastIndexOf( "@" );
157 String value = s[1].substring( 0, idx );
158 if ( s[1].endsWith( "S" ) )
159 {
160 ctx.put( s[0], "NULL".equalsIgnoreCase( value ) ? "" : value );
161 } else if ( s[1].endsWith( "B" ) )
162 {
163 ctx.put( s[0], "NULL".equalsIgnoreCase( value ) ? null : Boolean.valueOf( value ) );
164 } else if ( s[1].endsWith( "I" ) )
165 {
166 ctx.put( s[0], "NULL".equalsIgnoreCase( value ) ? null : new Integer( value ) );
167 } else if ( s[1].endsWith( "L" ) )
168 {
169 ctx.put( s[0], "NULL".equalsIgnoreCase( value ) ? null : new Long( value ) );
170 } else if ( s[1].endsWith( "D" ) )
171 {
172 ctx.put( s[0], "NULL".equalsIgnoreCase( value ) ? null : new Double( value ) );
173 } else if ( s[1].endsWith( "F" ) )
174 {
175 ctx.put( s[0], "NULL".equalsIgnoreCase( value ) ? null : new Float( value ) );
176 }
177 } else
178 {
179 ctx.put( s[0], s[1] );
180 }
181 } else
182 {
183 logger.error( "ignore {}", arg );
184 }
185 }
186 logger.info( "{}", ctx );
187
188 if ( ctx.containsKey( GlueBizControlConstants.SERVICE_NAME ) )
189 {
190 try
191 {
192 GlueBizProvider.getController().doAction( ctx );
193 } catch ( Throwable t )
194 {
195 if ( ctx.getException() != null )
196 {
197 // BeanCreationException µî GlueService ½ÇÇà Àü¿¡ ¹ß»ýµÈ ¿¡·¯¸¦ ó¸®Çϱâ À§ÇÔ.
198 ctx.setException( t );
199 } else
200 {
201 logger.error( "unknwon error", t );
202 }
203 t.printStackTrace();
204 }
205 } else if ( ctx.containsKey( "className" ) )
206 {
207 try
208 {
209 Object clz = Thread.currentThread().getContextClassLoader().loadClass( (String) ctx.get( "className" ) ).newInstance();
210 Method method = clz.getClass().getMethod( "runProgram", new Class[] { GlueContext.class } );
211 method.invoke( clz, new Object[] { ctx } );
212 if ( ctx.getException() != null )
213 {
214 logger.error( "UserException", ctx.getException() );
215 ctx.getException().printStackTrace();
216 }
217 // ctx.getException();
218 } catch ( InstantiationException e )
219 {
220 ctx.setException( e );
221 logger.error( "InstantiationException", e );
222 } catch ( IllegalAccessException e )
223 {
224 ctx.setException( e );
225 logger.error( "IllegalAccessException", e );
226 } catch ( ClassNotFoundException e )
227 {
228 ctx.setException( e );
229 logger.error( "ClassNotFoundException", e );
230 } catch ( SecurityException e )
231 {
232 ctx.setException( e );
233 logger.error( "SecurityException", e );
234 } catch ( NoSuchMethodException e )
235 {
236 ctx.setException( e );
237 logger.error( "NoSuchMethodException", e );
238 } catch ( IllegalArgumentException e )
239 {
240 ctx.setException( e );
241 logger.error( "IllegalArgumentException", e );
242 } catch ( InvocationTargetException e )
243 {
244 ctx.setException( e );
245 logger.error( "InvocationTargetException", e );
246 } catch ( Throwable t )
247 {
248 ctx.setException( t );
249 logger.error( "UserException", t );
250 }
251 } else
252 {
253 ctx.setException( new Exception( "Service is Null!" ) );
254 logger.info( "Service is Null!" );
255 }
256
257 } catch ( Exception e )
258 {
259 logger.error( "Exception", e );
260 e.printStackTrace();
261 } catch ( Throwable t )
262 {
263 logger.error( "Throwable", t );
264 t.printStackTrace();
265 } finally
266 {
267 long end = System.currentTimeMillis();
268 if ( !isLocalTest )
269 GlueSimpleJob.updateEndTime( args[0], end - start, ctx.getException() );
270 logger.info( "RequestID:[{}] EndTime[{}] RunTime:[{}]", requestId, new Date( end ), end - start );
271 }
272 System.exit( 0 );
273 }
274
275 private static void updateEndTime( String id, long runtime, Throwable throwable )
276 {
277 try
278 {
279 if ( "-1".equals( id ) )
280 {
281 return;
282 }
283 DataSource ds = applicationContext.getBean( "dataSource", DataSource.class );
284 logger.debug( "{}", JobConstants.SQL_PGM_END );
285 logger.trace( "{}", runtime );
286 logger.trace( "{}", throwable == null ? "END" : "ERROR" );
287 logger.trace( "{}", id );
288 Connection con = null;
289 PreparedStatement ps = null;
290 con = DataSourceUtils.getConnection( ds );
291 try
292 {
293 ps = con.prepareStatement( JobConstants.SQL_PGM_END );
294 ps.setObject( 1, runtime );
295 ps.setObject( 2, throwable == null ? "END" : "ERROR" );
296 ps.setObject( 3, new Long( id ) );
297 ps.executeUpdate();
298 con.commit();
299 } catch ( SQLException e )
300 {
301 logger.error( "fail to executeUpdate", e );
302 } finally
303 {
304 JdbcUtils.closeStatement( ps );
305 DataSourceUtils.releaseConnection( con, ds );
306 }
307 } catch ( Exception e )
308 {
309 logger.error( "fail to getConnection", e );
310 } catch ( Throwable t )
311 {
312 logger.error( "fail to getConnection", t );
313 }
314 }
315
316 private static void updateStartTime( String id, String pid )
317 {
318 try
319 {
320 if ( "-1".equals( id ) )
321 {
322 return;
323 }
324 DataSource ds = applicationContext.getBean( "dataSource", DataSource.class );
325 logger.debug( "{}", JobConstants.SQL_PGM_START );
326 logger.trace( "{}", "RUNNING" );
327 logger.trace( "{}", pid );
328 logger.trace( "{}", id );
329
330 Connection con = null;
331 PreparedStatement ps = null;
332 con = DataSourceUtils.getConnection( ds );
333 try
334 {
335 ps = con.prepareStatement( JobConstants.SQL_PGM_START );
336 ps.setObject( 1, "RUNNING" );
337 ps.setObject( 2, new Integer( pid ) );
338 ps.setObject( 3, new Long( id ) );
339 ps.executeUpdate();
340 con.commit();
341 } catch ( SQLException e )
342 {
343 logger.error( "fail to executeUpdate", e );
344 } catch ( Exception e )
345 {
346 logger.error( "fail to getConnection", e );
347 } catch ( Throwable t )
348 {
349 logger.error( "fail to getConnection", t );
350 } finally
351 {
352 JdbcUtils.closeStatement( ps );
353 DataSourceUtils.releaseConnection( con, ds );
354 }
355 } catch ( Exception e )
356 {
357 logger.error( "fail to getConnection", e );
358 } catch ( Throwable t )
359 {
360 logger.error( "fail to getConnection", t );
361 }
362 }
363 }