|
|
@@ -0,0 +1,138 @@
|
|
|
+package com.tsi.comm.server;
|
|
|
+
|
|
|
+import com.tsi.comm.server.config.ApplicationConfig;
|
|
|
+import com.tsi.comm.server.config.TsiCvimServerConfig;
|
|
|
+import com.tsi.comm.server.kafka.KafkaConsumerService;
|
|
|
+import com.tsi.comm.server.kafka.KafkaProducerService;
|
|
|
+import com.tsi.comm.server.process.dbms.TsiCvimDbmsProcess;
|
|
|
+import com.tsi.comm.server.process.logging.TsiCvimLoggingProcess;
|
|
|
+import com.tsi.comm.server.process.packet.TsiCvimPacketProcess;
|
|
|
+import com.tsi.comm.server.repository.ApplicationRepository;
|
|
|
+import com.tsi.comm.server.service.TsiCommServerService;
|
|
|
+import com.tsi.comm.server.tcp.TsiCvimServer;
|
|
|
+import com.tsi.comm.server.vo.TsiAlarmConfigVo;
|
|
|
+import com.tsi.comm.server.vo.mariadb.AbstractDbmsVo;
|
|
|
+import com.tsi.comm.server.vo.mariadb.AlarmOccrVo;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
+import javax.annotation.PreDestroy;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+//@Component
|
|
|
+public class ApplicationLifecycle {
|
|
|
+ private final ApplicationConfig applicationConfig;
|
|
|
+ private final TsiCvimServerConfig serverConfig;
|
|
|
+ private final TsiCommServerService tsiCommServerService;
|
|
|
+ private final KafkaConsumerService kafkaConsumerService;
|
|
|
+ private final KafkaProducerService kafkaProducerService;
|
|
|
+ private final TsiCvimPacketProcess packetProcess;
|
|
|
+ private final TsiCvimLoggingProcess loggingProcess;
|
|
|
+ private final TsiCvimDbmsProcess dbmsProcess;
|
|
|
+ private final TsiCvimServer cvimServer;
|
|
|
+
|
|
|
+ private String applicationName;
|
|
|
+ private int serverId = 0;
|
|
|
+
|
|
|
+ @PostConstruct
|
|
|
+ public void start() {
|
|
|
+ SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ log.info("");
|
|
|
+ log.info("************************************************************************************");
|
|
|
+ log.info("** TSI CVIM System **");
|
|
|
+ log.info("** CVIM Communication Server Program. **");
|
|
|
+ log.info("** [ver.1.0] **");
|
|
|
+ log.info("** startup: {}", sdfDate.format(new Date()));
|
|
|
+ log.info("************************************************************************************");
|
|
|
+
|
|
|
+ this.applicationConfig.setStartSchedule(false);
|
|
|
+ serverId = this.serverConfig.getServerId();
|
|
|
+
|
|
|
+ this.applicationName = TsiCommServerApplication.APPLICATION_NAME + "-" + this.serverConfig.getServerId();
|
|
|
+ ApplicationRepository.processStateVo.setProcessId(applicationName);
|
|
|
+
|
|
|
+ this.tsiCommServerService.init();
|
|
|
+ this.kafkaConsumerService.start();
|
|
|
+ this.kafkaProducerService.start();
|
|
|
+ this.packetProcess.start();
|
|
|
+ this.loggingProcess.start();
|
|
|
+ this.dbmsProcess.start();
|
|
|
+
|
|
|
+ // Netty 서버 시작은 백그라운드 스레드에서 실행되므로, 이 메서드를 블로킹하지 않습니다.
|
|
|
+ this.cvimServer.run();
|
|
|
+
|
|
|
+ this.serverConfig.setStartup(true);
|
|
|
+ try {
|
|
|
+ // 시스템 시작 알람 이력 저장
|
|
|
+ AlarmOccrVo alarm = new AlarmOccrVo(AbstractDbmsVo.DBMS_ALARM_OCCR_HS);
|
|
|
+ alarm.setAlarmCode(TsiAlarmConfigVo.SYS_00);
|
|
|
+ alarm.setAlarmTarget(applicationName);
|
|
|
+ alarm.setAlarmValue("Running");
|
|
|
+ this.tsiCommServerService.insertAlarmOccrHs(alarm);
|
|
|
+ this.tsiCommServerService.updateProcessState(0);
|
|
|
+ } catch(Exception e) {
|
|
|
+ log.error("Error during startup alarm logging", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.applicationConfig.setStartSchedule(true);
|
|
|
+ log.info("Application has been started successfully.");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Spring 컨텍스트가 종료될 때, 빈이 소멸되기 직전에 호출됩니다.
|
|
|
+ */
|
|
|
+ @PreDestroy
|
|
|
+ public void stop() {
|
|
|
+ SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ log.error("************************************************************************************");
|
|
|
+ log.error("** Application Terminating: {}", sdfDate.format(new Date()));
|
|
|
+
|
|
|
+ // 종료는 생성의 역순이 안전합니다.
|
|
|
+
|
|
|
+ // 1. 새로운 연결을 막습니다.
|
|
|
+ if (this.cvimServer != null) {
|
|
|
+ this.cvimServer.stop();
|
|
|
+ log.info("Netty Server stopped.");
|
|
|
+ }
|
|
|
+ if (this.kafkaConsumerService != null) {
|
|
|
+ this.kafkaConsumerService.shutdown();
|
|
|
+ log.info("Kafka Consumer stopped.");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 내부 처리 로직(워커 스레드 풀)을 종료합니다.
|
|
|
+ if (this.packetProcess != null) {
|
|
|
+ this.packetProcess.stop();
|
|
|
+ log.info("Packet Process stopped.");
|
|
|
+ }
|
|
|
+ if (this.loggingProcess != null) {
|
|
|
+ this.loggingProcess.stop();
|
|
|
+ log.info("Logging Process stopped.");
|
|
|
+ }
|
|
|
+ if (this.dbmsProcess != null) {
|
|
|
+ this.dbmsProcess.stop();
|
|
|
+ log.info("DBMS Process stopped.");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 외부로 나가는 통신(Kafka Producer)을 종료합니다.
|
|
|
+ if (this.kafkaProducerService != null) {
|
|
|
+ this.kafkaProducerService.shutdown();
|
|
|
+ log.info("Kafka Producer stopped.");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. DB에 최종 상태를 기록합니다.
|
|
|
+ if (this.tsiCommServerService != null) {
|
|
|
+ this.serverConfig.setStartup(false);
|
|
|
+ int serverId = this.serverConfig.getServerId();
|
|
|
+ this.tsiCommServerService.updateNodeStatusTerm(serverId);
|
|
|
+ // ... 시스템 종료 알람 저장 로직 ...
|
|
|
+ this.tsiCommServerService.updateProcessState(2);
|
|
|
+ log.info("Final DB states updated.");
|
|
|
+ }
|
|
|
+
|
|
|
+ log.error("************************************************************************************");
|
|
|
+ }
|
|
|
+}
|