diff --git a/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailLog.java b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailLog.java new file mode 100644 index 0000000..1c44edc --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailLog.java @@ -0,0 +1,47 @@ +package com.eactive.eai.rms.data.ext.djb.inflow; + + import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +import com.eactive.eai.data.entity.AbstractEntity; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NonNull; + +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) +@Entity +@Table(name = "TSEAIFR11") +public class InflowTokenFailLog extends AbstractEntity implements Serializable { + private static final long serialVersionUID = 1L; + + @EmbeddedId + @EqualsAndHashCode.Include + private InflowTokenFailLogId id; + + @Column(name = "EAISEVRINSTNCNAME", length = 20) + private String eaisevrinstncname; + + @Column(name = "EAISVCNAME", length = 30) + private String eaisvcname; + + @Column(name = "ADPTRBZWKGROUPNAME", length = 50) + private String adptrbzwkgroupname; + + @Column(name = "THRESHOLDPERSECOND") + private Long thresholdpersecond; + + @Column(name = "THRESHOLD") + private Long threshold; + + @Column(name = "THRESHOLDTIMEUNIT", length = 12) + private String thresholdtimeunit; + + @Override + public @NonNull InflowTokenFailLogId getId() { return id; } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailLogId.java b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailLogId.java new file mode 100644 index 0000000..85bc9a1 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailLogId.java @@ -0,0 +1,21 @@ +package com.eactive.eai.rms.data.ext.djb.inflow; + + import java.io.Serializable; + import javax.persistence.Column; + import javax.persistence.Embeddable; + import lombok.Data; + + @Data + @Embeddable + public class InflowTokenFailLogId implements Serializable { + private static final long serialVersionUID = 1L; + + @Column(name = "EAIBZWKDSTCD", length = 4) + private String eaibzwkdstcd; + + @Column(name = "MSGDPSTYMS", length = 17) + private String msgdpstyms; + + @Column(name = "EAISVCSERNO", length = 41) + private String eaisvcserno; + } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailRepository.java b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailRepository.java new file mode 100644 index 0000000..4ed620e --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailRepository.java @@ -0,0 +1,17 @@ +package com.eactive.eai.rms.data.ext.djb.inflow; + +import java.util.List; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import com.eactive.eai.data.jpa.BaseRepository; + +public interface InflowTokenFailRepository extends BaseRepository { + + @Query(nativeQuery = true, value = + " SELECT EAISVCNAME" + + " , COUNT(*) AS CNT" + + " FROM TSEAIFR11" + + " WHERE MSGDPSTYMS >= TO_CHAR(SYSTIMESTAMP - NUMTODSINTERVAL(:rangeMinute, 'MINUTE'), 'YYYYMMDDHH24MISSFF3')" + + " GROUP BY EAISVCNAME") + List countByEaisvcname(@Param("rangeMinute") long rangeMinute); +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailService.java b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailService.java new file mode 100644 index 0000000..af89a4a --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailService.java @@ -0,0 +1,30 @@ +package com.eactive.eai.rms.data.ext.djb.inflow; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + + +@Service +@Transactional +public class InflowTokenFailService { + + private static final Logger log = LoggerFactory.getLogger(InflowTokenFailService.class); + + @Autowired + private InflowTokenFailRepository inflowTokenFailRepository; + + public void checkRecentFails(long rangeMinute) { + List rows = inflowTokenFailRepository.countByEaisvcname(rangeMinute); + + for (InflowTokenFailSummary summary : rows) { + log.debug("유량제어 토큰 획득 실패: {} 최근 {}분 동안 {}건", summary.getEaisvcname(), rangeMinute, summary.getCnt()); + + //TOOD: 내부직원 알림 발송 + } + } +} diff --git a/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailSummary.java b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailSummary.java new file mode 100644 index 0000000..d5ea6b0 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/data/ext/djb/inflow/InflowTokenFailSummary.java @@ -0,0 +1,6 @@ +package com.eactive.eai.rms.data.ext.djb.inflow; + +public interface InflowTokenFailSummary { + String getEaisvcname(); + Long getCnt(); +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/job/InflowTokenFailMonitorJob.java b/src/main/java/com/eactive/eai/rms/ext/djb/job/InflowTokenFailMonitorJob.java new file mode 100644 index 0000000..0f7d1d9 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/ext/djb/job/InflowTokenFailMonitorJob.java @@ -0,0 +1,101 @@ +package com.eactive.eai.rms.ext.djb.job; + +import java.util.Date; +import java.util.concurrent.TimeUnit; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.Job; +import org.quartz.JobDataMap; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; + +import com.eactive.eai.rms.common.context.MonitoringContext; +import com.eactive.eai.rms.common.datasource.DataSourceContextHolder; +import com.eactive.eai.rms.common.datasource.DataSourceTypeManager; +import com.eactive.eai.rms.common.util.CommonUtil; +import com.eactive.eai.rms.data.ext.djb.inflow.InflowTokenFailService; +import com.eactive.eai.rms.onl.common.util.DateUtil; + +/** + * Job - Quartz Job + * TSEAIFR11 데이터를 10분마다 조회하여 데이터가 있는 경우(유량제어 토큰 획득 실패), 알림을 발송한다 + * + *

Cron Schedule 권장:

+ *
    + *
  • 기본: 0 0/10 * * * ? (매10분 1회 실행)
  • + *
+ * + *

Job 파라미터 (JobDataMap):

+ *
    + *
  • + * NONE + *
  • + *
+ * + */ + +@DisallowConcurrentExecution +public class InflowTokenFailMonitorJob implements Job { + + private static final Logger log = LoggerFactory.getLogger(InflowTokenFailMonitorJob.class); + + private transient MonitoringContext monitoringContext; + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + log.info("*** START InflowTokenFailMonitorJob run({})", CommonUtil.getToday("yyyy-MM-dd HH:mm")); + + long execMinute = 1; //default 배치 실행주기(분) + + Trigger trigger = context.getTrigger(); + Date prevFireTime = trigger.getPreviousFireTime(); + Date nextFireTime = trigger.getNextFireTime(); + + //1회 이상 배치가 실행된 경우, 배치 간격을 구하여 유량제어조회 구간 파라미터로 전달한다 + if (prevFireTime != null && nextFireTime != null) { + long diffMillis = nextFireTime.getTime() - prevFireTime.getTime(); + execMinute = TimeUnit.MILLISECONDS.toMinutes(diffMillis); + log.info("실행 주기: {}분", execMinute); + } + + ApplicationContext appContext; + try { + appContext = (ApplicationContext) context.getScheduler().getContext().get("applicationContext"); + } catch (SchedulerException e) { + log.error("applicationContext get module error", e); + return; + } + + monitoringContext = (MonitoringContext) appContext.getBean("monitoringContext"); + InflowTokenFailService service = appContext.getBean(InflowTokenFailService.class); + + DataSourceContextHolder.setDataSourceType( + DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW)); + try { + service.checkRecentFails(execMinute); + } catch (Exception e) { + log.error("InflowTokenFailMonitorJob execution failed", e); + throw new JobExecutionException(e); + } finally { + DataSourceContextHolder.clearDataSourceType(); + } + + log.info("*** END InflowTokenFailMonitorJob run({})", DateUtil.getDateTime("yyyy-MM-dd HH:mm")); + } + + + + /** + * 개발 모드 여부 확인 + * @return eai.systemmode=D 이면 true + */ + private boolean isDevMode() { + String systemMode = System.getProperty("eai.systemmode", ""); + return "D".equalsIgnoreCase(systemMode); + } +}