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 }