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