package com.eactive.eai.common.web; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetAddress; import java.nio.charset.Charset; import java.rmi.RemoteException; import java.security.Security; import java.util.Arrays; import javax.sql.DataSource; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.remoting.rmi.RmiServiceExporter; import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; import com.eactive.eai.common.dao.Keys; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.lifecycle.LifecycleException; import com.eactive.eai.common.lifecycle.LifecycleManager; import com.eactive.eai.common.logger.async.AsyncLoggingPoolManager; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.routing.rmi.RemoteProxy; import com.eactive.eai.common.routing.rmi.RemoteProxyImpl; import com.eactive.eai.common.server.EAIServerManager; import com.eactive.eai.common.server.EAIServerVO; import com.eactive.eai.common.state.ElinkStateManager; import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.ServiceLocator; import com.eactive.eai.common.util.ServiceLocatorException; import com.eactive.eai.env.ConfigKeys; import com.eactive.eai.env.ElinkConfig; import com.eactive.eai.common.logger.async.AsyncHttpLoggingPoolManager; /** * eLink FrameWork이 초기화(Deploy)될 때 실행되어야 할 작업을 정의 */ @SuppressWarnings("deprecation") public class AppInitializer implements InitializingBean, DisposableBean { RemoteProxy remoteProxy = new RemoteProxyImpl(); Class serviceInterface = RemoteProxy.class; RmiServiceExporter rmiServiceExporter = new org.springframework.remoting.rmi.RmiServiceExporter(); @Autowired private LifecycleManager lifecycleManager; @Autowired private EAIServerManager eaiServerManager; private DataSource dataSource; private String instName; private String instPort; private String tableOwner; private String scalable; private boolean isScalable; private String routerUrl; private String systemType; // eLink System Type private String systemMode = "D"; // eLink System Mode : [P/T/D/S private String eaiServerExtractor = ""; private String jndiName = ""; private int shutdownWaitSecs = 60; private int shutdownWaitIntervalMs = 500; private static final String SHUTDOWN_WAIT_SECS = "shutdown.wait.secs"; private static final String SHUTDOWN_WAIT_INTERVALMS = "shutdown.wait.intervalms"; public String getJndiName() { return jndiName; } public void setJndiName(String jndiName) { this.jndiName = jndiName; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void setInstName(String instName) { this.instName = instName; } public void setTableOwner(String tableOwner) { this.tableOwner = tableOwner; } public void setScalable(String scalable) { this.scalable = scalable; } public String getScalable() { return scalable; } public String getSystemType() { return systemType; } public void setSystemType(String systemType) { this.systemType = systemType; } public void setSystemMode(String systemMode) { this.systemMode = systemMode; } private String rmiPort; private String rmiServicePort; public String getRmiPort() { return rmiPort; } public void setRmiPort(String rmiPort) { this.rmiPort = rmiPort; } public String getRmiServicePort() { return rmiServicePort; } public void setRmiServicePort(String rmiServicePort) { this.rmiServicePort = rmiServicePort; } public String getRouterUrl() { return routerUrl; } public void setRouterUrl(String routerUrl) { this.routerUrl = routerUrl; } public String getInstPort() { return instPort; } public void setInstPort(String instPort) { this.instPort = instPort; } public String getEaiServerExtractor() { return eaiServerExtractor; } public void setEaiServerExtractor(String eaiServerExtractor) { this.eaiServerExtractor = eaiServerExtractor; } public int getShutdownWaitSecs() { return shutdownWaitSecs; } public void setShutdownWaitSecs(int shutdownWaitSecs) { this.shutdownWaitSecs = shutdownWaitSecs; } public int getShutdownWaitIntervalMs() { return shutdownWaitIntervalMs; } public void setShutdownWaitIntervalMs(int shutdownWaitIntervalMs) { this.shutdownWaitIntervalMs = shutdownWaitIntervalMs; } @SuppressWarnings("deprecation") private void initRmiServer(int registryPort, int servicePort) throws RemoteException { rmiServiceExporter.setServiceName("RemoteProxy"); rmiServiceExporter.setService(remoteProxy); rmiServiceExporter.setServiceInterface(serviceInterface); rmiServiceExporter.setRegistryPort(registryPort); rmiServiceExporter.setServicePort(servicePort); rmiServiceExporter.setAlwaysCreateRegistry(true); rmiServiceExporter.afterPropertiesSet(); } private void stopRmiServer() { if(rmiServiceExporter != null) { try { rmiServiceExporter.destroy(); } catch (RemoteException e) { e.printStackTrace(); } } } /** * eLink FrameWork의 웹어플리케이션이 될 때 초기화 작업을 수행 **/ private void init() { ElinkStateManager.getInstance().setWaitMaxMs(shutdownWaitSecs * 1000); ElinkStateManager.getInstance().setSleepIntervalMs(shutdownWaitIntervalMs); ElinkStateManager.getInstance().starting(); if (StringUtils.isBlank(System.getProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEM_TYPE))) { if (StringUtils.isNotBlank(systemType)) { System.setProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEM_TYPE, systemType); } } if (StringUtils.isBlank(System.getProperty("scalable"))) { if (StringUtils.isNotBlank(scalable)) { System.setProperty("scalable", scalable); } } if (StringUtils.isBlank(System.getProperty("router.url"))) { if (StringUtils.isNotBlank(routerUrl)) { System.setProperty("router.url", routerUrl); } } if (StringUtils.isBlank(System.getProperty("eai.server.extractor"))) { if (StringUtils.isNotBlank(eaiServerExtractor)) { System.setProperty("eai.server.extractor", eaiServerExtractor); } } this.isScalable = BooleanUtils.toBoolean(System.getProperty("scalable")); if (this.isScalable) { String uniqueInstName = instName; if (StringUtils.isBlank(uniqueInstName)) { uniqueInstName = RandomStringUtils.randomAlphabetic(20); // }else if(uniqueInstName.length() > 20){ // int l = uniqueInstName.length(); // uniqueInstName = uniqueInstName.substring(l-14, l) + "-" + RandomStringUtils.randomAlphabetic(5); } System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, uniqueInstName); } else { String serverName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); if (serverName == null) { System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, instName); } } String instPort = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_PORT); if (instPort == null) { System.setProperty(com.eactive.eai.common.server.Keys.SERVER_PORT, this.instPort); } /** * OpenJDK 11 이상 사용 시 -Dfile.encoding 프로퍼티로 ms949, euc-kr * Charset.defaultCharset()의 값이 지정되지 않는 지정할 수 없는 버그가 존재한다 * 해당 버그를 Charset을 초기화 하여 우회하는 방법으로 처리한다. */ Field charset = null; try { charset = Charset.class.getDeclaredField("defaultCharset"); charset.setAccessible(true); charset.set(null, null); } catch (Exception e) { e.printStackTrace(); } String serverName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); if (serverName == null) { System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, instName); } String tOwner = System.getProperty(Keys.TABLE_OWNER_KEY); if (tOwner == null) { System.setProperty(Keys.TABLE_OWNER_KEY, tableOwner); } String sMode = System.getProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE); if (sMode == null) { System.setProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE, systemMode); } // set Spring dataSource to ServiceLoactor try { String datasourceName = System.getProperty(Keys.JDBC_NAME_KEY); if(StringUtils.isEmpty(datasourceName)) { System.setProperty(Keys.JDBC_NAME_KEY, this.jndiName); } ServiceLocator sl = ServiceLocator.getInstance(); sl.putDataSource(Keys.EAI_DATASOURCE, dataSource); System.out.println("\n@@ " + Keys.EAI_DATASOURCE + " = " + dataSource); } catch (ServiceLocatorException e1) { System.out.println("ServiceLocator error"); } System.out.println("\n@@ eLink Framework(JSON_TUNE) ====================================================="); System.out.println("@ eLink System Config Initializing -----------------------"); try { if (StringUtils.isBlank(this.tableOwner)) { System.out.println("=========================================================================="); System.out.println("# E R R O R : eLink System Configuration"); System.out.println("# Check Start Script Rule table Owner : -D" + com.eactive.eai.common.dao.Keys.TABLE_OWNER_KEY + "="); System.out.println("# Check Start Script eLink System Mode : -D" + com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE + "="); System.out.println("# eLink System Mode : [P/T/D/S]"); System.out.println("=========================================================================="); throw new Exception(" Rule Table Owner Not Configured "); } if (StringUtils.isBlank(this.systemMode)) { System.out.println("=========================================================================="); System.out.println("# E R R O R : eLink System Configuration"); System.out.println("# Check Start Script Rule table Owner : -D" + com.eactive.eai.common.dao.Keys.TABLE_OWNER_KEY + "="); System.out.println("# Check Start Script eLink System Mode : -D" + com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE + "="); System.out.println("# eLink System Mode : [P/T/D/S]"); System.out.println("=========================================================================="); throw new Exception(" eLink System Mode Not Configured "); } System.out.println("=========================================================================="); System.out.println("# S U C C E S S : eLink System Configuration"); System.out.println("# Rule table Owner : " + this.tableOwner); System.out.println("# Rule JDBC Name : " + com.eactive.eai.common.dao.Keys.EAI_DATASOURCE); System.out.println("# eLink System Mode : " + this.systemMode); System.out.println("# eLink System Mode : [P(Product)/T(Test)/D(Develop)/S(Staging)]"); System.out.println( String.format("# %s : %s", ConfigKeys.USE_INTERNAL_TOPIC, ElinkConfig.isUseCacheTopic())); System.out.println("=========================================================================="); System.out.println( String.format("# %s : %s", SHUTDOWN_WAIT_SECS, shutdownWaitSecs) ); System.out.println( String.format("# %s : %s", SHUTDOWN_WAIT_INTERVALMS, shutdownWaitIntervalMs) ); } catch (Exception e) { throw new RuntimeException("eLink System Configuration Error - " + e.toString()); } try { PropManager.getInstance().start(); } catch (LifecycleException e) { throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RFCEAICWB001")); } try { Logger.doConfigure(); } catch (Exception e) { System.out.println("Logger.doConfigure error"); } Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); /** * 서버정보 입력 */ if (this.isScalable) { try { EAIServerVO vo = new EAIServerVO(); vo.setAddress(InetAddress.getLocalHost().getHostAddress()); vo.setHostName(InetAddress.getLocalHost().getHostName()); vo.setName(System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY)); // scalable merge // vo.setPort(System.getProperty("tomcat.port.http")); vo.setPort(System.getProperty("inst.Port")); vo.setRouterUrl(System.getProperty("router.url")); System.out.println("----------------------------"); System.out.println(vo.toString()); System.out.println("----------------------------"); //addServer 에서 존재여부 체크해서 updateg함 eaiServerManager.addServer(vo); logger.info("Success Insert Server Info!!!!"); System.out.println("Success Insert Server Info!!!!"); } catch (Exception e) { logger.error("Refresh Server Info Error~~", e); System.out.println("Refresh Server Info Error~~" + e.getMessage()); } } // print system config to logger logger.warn("=========================================================================="); logger.warn("# S U C C E S S : eLink System Configuration"); logger.warn("# Rule table Owner : " + this.tableOwner); logger.warn("# System Mode : " + this.systemMode); logger.warn("# System Mode : [P(Product)/T(Test)/D(Develop)/S(Staging)]"); logger.warn("=========================================================================="); // init RMI Server String pRmiPort = System.getProperty("eai.rmiport"); if (pRmiPort != null) { this.rmiPort = pRmiPort; } String pRmiServicePort = System.getProperty("eai.rmiserviceport"); if (pRmiServicePort != null) { this.rmiServicePort = pRmiServicePort; } Arrays.stream(Security.getProviders()) .forEach(p -> System.out.println("JavaSecurityProviders=" + p.getName())); try { logger.warn("\n@@ eLink RMI Register Port : " + rmiPort + ", Service Port : " + rmiServicePort); initRmiServer(Integer.parseInt(rmiPort), Integer.parseInt(rmiServicePort)); } catch (NumberFormatException e2) { logger.error("eLink System RMI Server Configuration Error check port", e2); throw new RuntimeException("eLink System RMI Server Configuration Error check port - " + e2.toString()); } catch (RemoteException e2) { logger.error("eLink System RMI Server Start Error ", e2); throw new RuntimeException("eLink System RMI Server Start Error - " + e2.toString()); } // MonitoringContextFactory 기동 try { Class clazz = Class.forName("com.eactive.eai.rms.client.context.MonitoringContextFactory"); Object factory = clazz.newInstance(); Method method = clazz.getMethod("create"); method.invoke(factory); logger.warn("EMSCLIENT AGENT STARTED"); } catch (InvocationTargetException e) { logger.error("EMSCLIENT AGENT CANNOT START - " + e.getTargetException().toString(), e.getTargetException()); e.getTargetException().printStackTrace(); } catch (Throwable e) { logger.error("EMSCLIENT AGENT CANNOT START - " + e.toString(), e); } logger.warn("@ eLink Application Initializing -------------------------"); logger.warn(ElinkConfig.getConfigLog()); if (ElinkConfig.isUseAsyncLogging()) { try { logger.warn("START AsyncLoggingPoolManager"); AsyncLoggingPoolManager.getInstance().start(); logger.warn("SUCCESS AsyncLoggingPoolManager"); } catch (LifecycleException e) { logger.error("START AsyncLoggingPoolManager failed.", e); } try { logger.warn("START AsyncHttpLoggingPoolManager"); AsyncHttpLoggingPoolManager.getInstance().start(); logger.warn("SUCCESS AsyncHttpLoggingPoolManager"); } catch (LifecycleException e) { logger.error("START AsyncHttpLoggingPoolManager failed.", e); } } try { lifecycleManager.start(); } catch (LifecycleException e) { throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB002")); } ElinkStateManager.getInstance().started(); } /** * eLink FrameWork의 웹어플리케이션이 Undeploy될 때 초기화된 Manager들을 중지시킴 **/ public void destroy() { Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); if (logger.isWarn()) logger.warn("@ eLink Application Check current transactions."); // Check current transaction & wait specific seconds until finish ElinkStateManager.getInstance().stop(); if (logger.isWarn()) logger.warn("@ eLink Application destroying."); logger.warn("stopRmiServer"); stopRmiServer(); // MonitoringContextFactory 중지 try { Class clazz = Class.forName("com.eactive.eai.rms.client.context.MonitoringContextFactory"); Object factory = clazz.newInstance(); Method method = clazz.getMethod("stop"); method.invoke(factory); logger.warn("EMSCLIENT AGENT STOPPED"); } catch (InvocationTargetException e) { logger.error("EMSCLIENT AGENT CANNOT STOP - " + e.getTargetException().toString(), e.getTargetException()); e.getTargetException().printStackTrace(); } catch (Throwable e) { logger.error("EMSCLIENT AGENT CANNOT STOP - " + e.toString(), e); } /** * 서버정보 삭제 */ if (this.isScalable) { String instanceName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); logger.info("Starting, Delete Server Info: " + instanceName); System.out.println("Starting, Delete Server Info: " + instanceName); if (StringUtils.isNotBlank(instanceName)) { try { eaiServerManager.removeServer(instanceName); logger.info("Success Delete Server Info: " + instanceName); System.out.println("Success Delete Server Info: " + instanceName); } catch (Exception e) { logger.error("Delete Server Info Error~~", e); System.out.println("Delete Server Info Error~~" + instanceName + e.getMessage()); } } } try { lifecycleManager.stop(); } catch (LifecycleException e) { throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB002")); } try { PropManager.getInstance().stop(); } catch (LifecycleException e) { throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB004")); } try { SocketAdapterManager.getInstance().stop(); } catch (Exception e) { throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB005")); } if (ElinkConfig.isUseAsyncLogging()) { try { logger.warn("STOP AsyncLoggingPoolManager"); AsyncLoggingPoolManager.getInstance().stop(); logger.warn("STOPPED AsyncLoggingPoolManager"); } catch (LifecycleException e) { logger.error("STOP AsyncLoggingPoolManager failed.", e); } } logger.warn("STOP Logger"); Logger.stop(); System.out.println("\n\n"); } @Override public void afterPropertiesSet() throws Exception { init(); } }