| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- 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.getMessage());
- }
- 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("************************************************************************************");
- }
- }
|