commit d9d9fe10afd0109feb5b30ca9deffd7100127edd Author: MonHun Date: Sun Feb 11 22:19:23 2024 +0900 win 0211 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..bf82ff0 Binary files /dev/null and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..ca5ab4b --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar diff --git a/cfg/udpsocket.xml b/cfg/udpsocket.xml new file mode 100644 index 0000000..a3565fd --- /dev/null +++ b/cfg/udpsocket.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/ipworks-local-1.0.0.jar b/lib/ipworks-local-1.0.0.jar new file mode 100644 index 0000000..557d507 Binary files /dev/null and b/lib/ipworks-local-1.0.0.jar differ diff --git a/lib/state-spring-boot-starter-1.0.3.jar b/lib/state-spring-boot-starter-1.0.3.jar new file mode 100644 index 0000000..4f5a7df Binary files /dev/null and b/lib/state-spring-boot-starter-1.0.3.jar differ diff --git a/lib/tibero-jdbc-7.0.0.jar b/lib/tibero-jdbc-7.0.0.jar new file mode 100644 index 0000000..69b9029 Binary files /dev/null and b/lib/tibero-jdbc-7.0.0.jar differ diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,188 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..449631a --- /dev/null +++ b/pom.xml @@ -0,0 +1,133 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.8 + + + kr.gmtc.gw + + standstatus + 0.0.1-SNAPSHOT + EyeGW_StandStatus + Demo project for Spring Boot + + + + local-repository + local-repository + file:${project.basedir}/lib + + + + + 1.8 + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.kafka + spring-kafka + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + + 3.0.0 + + + com.tmax.tibero + tibero-jdbc + 7 + system + ${basedir}/lib/tibero-jdbc-7.0.0.jar + + + + + + org.projectlombok + lombok + 1.18.24 + provided + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + ipworks.local + ipworks-local-1.0.0 + system + 1.0.0 + ${basedir}/lib/ipworks-local-1.0.0.jar + + + + kr.gmt.so + state-spring-boot-starter + 1.0.3 + system + ${basedir}/lib/state-spring-boot-starter-1.0.3.jar + + + + + + + + + EyeANA_StandStatus + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + + diff --git a/src/main/java/kr/gmtc/gw/comp/rest/ServiceQueManager.java b/src/main/java/kr/gmtc/gw/comp/rest/ServiceQueManager.java new file mode 100644 index 0000000..d748986 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/comp/rest/ServiceQueManager.java @@ -0,0 +1,188 @@ +package kr.gmtc.gw.comp.rest; + +import java.io.IOException; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.gw.comp.rest.vo.RestServiceData; +import kr.gmtc.gw.comp.thread.CustomThread; +import kr.gmtc.gw.standstatus.utils.CmmnUtil; + +public class ServiceQueManager { + + HashMap> serviceQueue; + Map> serviceList; + + private boolean serviceRunnig = false; + private Integer scvQcount; + private Integer scvQmaxCount; + private Integer scvQdiffTime; + private Integer scvQclearTime; + + private CustomThread serviceQClearThread; + + protected Logger logger; + + public ServiceQueManager(Map> serviceList, boolean serviceRunnig){ + + this.serviceList = serviceList; + this.serviceRunnig = serviceRunnig; + + logger = LoggerFactory.getLogger(this.getClass()); + + // 업무 스레드 생성, 대기 없이 무한반복 + serviceQClearThread = new CustomThread("serviceQClearThread", this, CustomThread.NO_SLEEP, this::serviceQClear, null, false); + } + + public void start(){ + + // 전송용 Queue 생성 + createList(); + + //serviceQClearThread.start(); + + } + + // 설정에따라 REST용 서비스 큐 생성 + @SuppressWarnings("unchecked") + public void createQueue() { + + // String className = "java.util.Queue"; + //Class cls = Class.forName(className); + + for(int idx=0; idx obj = null; + + try { + + obj = (Queue) java.util.LinkedList.class.newInstance(); + + } catch (InstantiationException e) { + logger.error("[ServiceQueManager] createQueue-InstantiationException : " + CmmnUtil.getStatckTrace(e)); + } catch (IllegalAccessException e) { + logger.error("[ServiceQueManager] createQueue-IllegalAccessException : " + CmmnUtil.getStatckTrace(e)); + } + + serviceQueue.put(idx, obj); + + } + + } + + @SuppressWarnings("unchecked") + public void createList() { + + // String className = "java.util.Queue"; + //Class cls = Class.forName(className); + + for(int idx=0; idx obj = null; + + try { + + obj = (LinkedList) java.util.LinkedList.class.newInstance(); + + } catch (InstantiationException e) { + logger.error("[ServiceQueManager] createQueue-InstantiationException : " + CmmnUtil.getStatckTrace(e)); + } catch (IllegalAccessException e) { + logger.error("[ServiceQueManager] createQueue-IllegalAccessException : " + CmmnUtil.getStatckTrace(e)); + } + + serviceList.put(idx, obj); + + } + + } + + private void serviceQClear() throws InterruptedException, IOException { + + String sRecvTime = ""; + + RestServiceData jsonData; + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + + LocalDateTime dateTime; + + int iQcnt = 0; + + if(serviceRunnig) return; + + try { + + for(int idx=0; idx scvQmaxCount ) { + + jsonData = serviceQueue.get(idx).peek(); + + // sRecvTime = jsonData.getRecptn_dt(); + + dateTime = LocalDateTime.parse(sRecvTime, formatter); + + Duration diff = Duration.between(dateTime, LocalDateTime.now()); + + if( scvQclearTime > 0 && diff.toMillis() > scvQclearTime) { // 일정시간 미사용으로 판단 + serviceQueue.get(idx).clear(); + logger.info("[MainController] serviceQClear : " + (idx +1) +"번 Queue 장기 미사용으로 초기화 (" + iQcnt +"건), 설정시간:" + scvQclearTime); + } + else if( diff.toMillis() > scvQdiffTime) { // 데이터 과적재 + + iQcnt = serviceQueue.get(idx).size(); + int iPollCnt = iQcnt - scvQmaxCount; + + while (iQcnt - scvQmaxCount >= 0) { + serviceQueue.get(idx).poll(); + iQcnt--; + + } + + logger.info("[MainController] serviceQpoll : " + (idx +1) +"번 Queue 일부 버림 (" + iPollCnt +"건), 설정시간:" + scvQdiffTime + " 설정건수:"+ scvQmaxCount); + } + } + } + + + Thread.sleep(1000); + } catch (InterruptedException e) { + logger.error("[MainController] serviceQClear-InterruptedException : " + CmmnUtil.getStatckTrace(e)); + + } catch (Exception e) { + logger.error("[MainController] serviceQClear-Exception : " + CmmnUtil.getStatckTrace(e) + ">> " + sRecvTime.toString() ); + } + } + + public void setScvQcount(Integer scvQcount) { + this.scvQcount = scvQcount; + } + + public void setScvQmaxCount(Integer scvQmaxCount) { + this.scvQmaxCount = scvQmaxCount; + } + + public void setScvQdiffTime(Integer scvQdiffTime) { + this.scvQdiffTime = scvQdiffTime; + } + + public void setScvQclearTime(Integer scvQclearTime) { + this.scvQclearTime = scvQclearTime; + } + + + + + +} diff --git a/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceData.java b/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceData.java new file mode 100644 index 0000000..9197255 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceData.java @@ -0,0 +1,29 @@ +package kr.gmtc.gw.comp.rest.vo; + +import kr.gmtc.gw.standstatus.vo.StandSttusVO; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class RestServiceData extends StandSttusVO { + + private String cctv_ip; + private String clsgn; + + RestServiceData(){} + + public RestServiceData(String stand_no, String cctv_id){ + this.setStand_no(stand_no); + this.setCctv_id(cctv_id); + this.setStand_sttus_ty("0"); + } + + + + + + + + +} diff --git a/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceHeader.java b/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceHeader.java new file mode 100644 index 0000000..eb37585 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceHeader.java @@ -0,0 +1,15 @@ +package kr.gmtc.gw.comp.rest.vo; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class RestServiceHeader { + + private String result_code; // 결과코드 + private String result_msg; // 결과메시지 + + + +} diff --git a/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceVO.java b/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceVO.java new file mode 100644 index 0000000..ed77a8d --- /dev/null +++ b/src/main/java/kr/gmtc/gw/comp/rest/vo/RestServiceVO.java @@ -0,0 +1,23 @@ +package kr.gmtc.gw.comp.rest.vo; + +import java.util.List; + +public class RestServiceVO { + + private RestServiceHeader header; + private List data; + + public RestServiceHeader getHeader() { + return header; + } + public void setHeader(RestServiceHeader header) { + this.header = header; + } + public List getData() { + return data; + } + public void setData(List data) { + this.data = data; + } + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/comp/thread/CustomThread.java b/src/main/java/kr/gmtc/gw/comp/thread/CustomThread.java new file mode 100644 index 0000000..0271fe4 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/comp/thread/CustomThread.java @@ -0,0 +1,113 @@ +package kr.gmtc.gw.comp.thread; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.gw.comp.thread.handler.CustomThreadOnTerminate; +import kr.gmtc.gw.comp.thread.handler.CustomThreadWork; + +public class CustomThread extends Thread{ + + /* 대기시간 없음 */ + public static final long NO_SLEEP = 0; + /* 1밀리 초 */ + public static final long SLEEP_MILLI_SEC = 1; + /* 1초 */ + public static final long SLEEP_SECOND = 1000; + /* 30초 */ + public static final long SLEEP_HALF_MINIUTE = 30000; + /* 1분 */ + public static final long SLEEP_MINIUTE = 60000; + + public final String controllClassName; + public final long repeatMiliSec; + public final CustomThreadWork definedWork; + public final CustomThreadOnTerminate definedTerminate; + public final Logger logger; + private boolean running; + + /** + * 인터럽트를 받을 시 스레드가 종료됨.
+ * {@link Thread#sleep(long)} 기반으로 재실행 간격을 설정하므로 정확한 실행시간을 보장하지 않음.
+ * 정확한 실행시간 보장이 필요 할 경우 sleep 간격을 짧게 설정하고 호출위치에서 시간확인
+ * 정상적인 종료는 {@link #gracefulStop()}으로 종료함 + * @param threadName 스레드 이름 + * @param controllClass 스레드 관리 클래스, 일반적으로 this 사용 + * @param repeatMiliSec Sleep 시간(밀리 초), 0이하의 경우 대기시간 없음 + * @param definedWork 반복할 작업 + * @param definedTerminate 스레드가 인터럽트에 의해 종료될 경우 할 작업 + * @param autoStart 생성즉시 실행 + */ + + public CustomThread(String threadName, Object controllClass, long repeatMiliSec, + CustomThreadWork definedWork, CustomThreadOnTerminate definedTerminate, boolean autoStart) { + + if (definedWork == null) { + throw new IllegalArgumentException("[CustomThread] - definedWork is null."); + } + + this.definedWork = definedWork; + this.definedTerminate = definedTerminate; + this.controllClassName = controllClass == null ? "" : controllClass.getClass().getSimpleName(); + this.repeatMiliSec = repeatMiliSec > 0 ? repeatMiliSec : 0; + this.logger = LoggerFactory.getLogger(CustomThread.class); + this.running = false; + + setName(threadName); + setDaemon(true); + if (autoStart) { + this.start(); + } + } + + + @Override + public void run() { + logger.info("[CustomThread-"+getName()+"] Started."); + while ( this.running && !this.isInterrupted()) { + try { + try { + this.definedWork.work(); + } finally { + if (this.repeatMiliSec > 0) { + Thread.sleep(this.repeatMiliSec); + } + } + } catch(InterruptedException e) { // 인터럽트 수신시 종료 + logger.error("[CustomThread-"+getName()+"] Interrupted. "+ e.toString()); + Thread.currentThread().interrupt(); + break; + } catch(Exception e) { // 처리되지 않은 예외 로깅, 예외에 의한 무한루프에 주의 + logger.error("[CustomThread-"+getName()+"] " + e.toString() + ":" + e.getStackTrace()[0] ); + } + } + + if(this.definedTerminate != null) { + this.definedTerminate.onTerminate(); + } + + logger.error("[CustomThread-"+ getName()+"] Stoped."); + + } + + @Override + public String toString() { + + return "CustomThread [controllClass=" + this.controllClassName + ", threadName=" + getName() + + ", runnig=" + this.running + ", alive=" + isAlive()+ ", repeatMiliSec=" + this.repeatMiliSec + + ", definedTerminate=" + (this.definedTerminate == null ? "no" : "yes") + "]"; + } + + @Override + public synchronized void start() { + this.running = true; + super.start(); + } + + /** + * 스레드 정상종료, 진행중인 작업 완료 후 종료됨. + */ + public void gracefulStop() { + this.running = false; + } +} diff --git a/src/main/java/kr/gmtc/gw/comp/thread/handler/CustomThreadOnTerminate.java b/src/main/java/kr/gmtc/gw/comp/thread/handler/CustomThreadOnTerminate.java new file mode 100644 index 0000000..8f6930b --- /dev/null +++ b/src/main/java/kr/gmtc/gw/comp/thread/handler/CustomThreadOnTerminate.java @@ -0,0 +1,6 @@ +package kr.gmtc.gw.comp.thread.handler; + +@FunctionalInterface +public interface CustomThreadOnTerminate { + public void onTerminate(); +} diff --git a/src/main/java/kr/gmtc/gw/comp/thread/handler/CustomThreadWork.java b/src/main/java/kr/gmtc/gw/comp/thread/handler/CustomThreadWork.java new file mode 100644 index 0000000..4d3d156 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/comp/thread/handler/CustomThreadWork.java @@ -0,0 +1,6 @@ +package kr.gmtc.gw.comp.thread.handler; + +@FunctionalInterface +public interface CustomThreadWork { + public void work() throws Exception; +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/StandStatusApplication.java b/src/main/java/kr/gmtc/gw/standstatus/StandStatusApplication.java new file mode 100644 index 0000000..34054c1 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/StandStatusApplication.java @@ -0,0 +1,31 @@ +package kr.gmtc.gw.standstatus; + +import java.time.ZoneId; +import java.util.TimeZone; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.ApplicationPidFileWriter; +import org.springframework.boot.system.ApplicationHome; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableScheduling +@SpringBootApplication +public class StandStatusApplication { + public static void main(String[] args) { + ApplicationHome home = new ApplicationHome(StandStatusApplication.class); + String root = home.getDir().getPath(); + + System.setProperty("user.dir", root); + + TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("UTC"))); + + Thread.currentThread().setName("JVM - Main"); + + SpringApplication springApplication = new SpringApplication(StandStatusApplication.class); + + springApplication.addListeners(new ApplicationPidFileWriter("./application.pid")); + springApplication.run(args); + + } +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/component/AnalysisAlarmStatus.java b/src/main/java/kr/gmtc/gw/standstatus/component/AnalysisAlarmStatus.java new file mode 100644 index 0000000..60ac834 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/component/AnalysisAlarmStatus.java @@ -0,0 +1,312 @@ +package kr.gmtc.gw.standstatus.component; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.DependsOn; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.gw.comp.rest.vo.RestServiceData; +import kr.gmtc.gw.comp.thread.CustomThread; +import kr.gmtc.gw.standstatus.database.datasource2.IcSelectDao; +import kr.gmtc.gw.standstatus.database.dto.DataLoadDTO; +import kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap; +import kr.gmtc.gw.standstatus.vo.AiAnalyzeStandSttus; +import kr.gmtc.gw.standstatus.vo.AlarmMsgVO; +import kr.gmtc.gw.standstatus.vo.AlarmTargetVO; +import kr.gmtc.gw.standstatus.vo.AlarmVO; +import kr.gmtc.gw.standstatus.vo.AreaVO; + +@Component +@DependsOn(value = {"serviceList"}) +public class AnalysisAlarmStatus { + + private Logger logger; + + Queue alamMsgQ; + LinkedList alamEndChkList; + + @Autowired + private IcSelectDao icSelectDao; + + private final ObjectMapper objMapper = new ObjectMapper(); + + @Resource(name = "dataLoadDTO") + private DataLoadDTO dto; + + @Resource(name = "serviceList") + private Map> serviceList; + + private LinkedList standSttusList; + + private CustomThread cThread_Analyze_Alarm_Start; + private CustomThread cThread_Analyze_Alarm_End; + + public AnalysisAlarmStatus(Queue alamMsgQ, LinkedList alamEndChkList){ + logger = LoggerFactory.getLogger(this.getClass()); + + this.alamMsgQ = alamMsgQ; + this.alamEndChkList = alamEndChkList; + + cThread_Analyze_Alarm_Start = new CustomThread("analysisAlarmStart", this, CustomThread.NO_SLEEP, this::analysis_Stand_sttus_alarm_start, null, false); + cThread_Analyze_Alarm_End = new CustomThread("analysisAlarmEnd", this, CustomThread.NO_SLEEP, this::analysis_Stand_sttus_alarm_end, null, false); + + start(); + } + + private void start(){ + + cThread_Analyze_Alarm_Start.start(); + cThread_Analyze_Alarm_End.start(); + + } + + + // 주기장 알림 상황 분석(상황시작) + public void analysis_Stand_sttus_alarm_start() throws InterruptedException{ + + if(serviceList == null || serviceList.size() == 0 || dto == null || dto.getDb_FltDep().size() == 0 ) { + + Thread.sleep(1000); + return; + } + + + for( DataLoadHashMap mapDep : dto.getDb_FltDep()){ + + String sActStandOff = mapDep.getItemString("ACTL_STTAND_OFF_DT"); + String sPdcIsue = mapDep.getItemString("PDC_ISUE_TM"); + String sStandNo = mapDep.getItemString("STAND_NO"); + String sClsgn = mapDep.getItemString("CLSGN"); + + if( !sActStandOff.equals("") && sPdcIsue.equals("")){ + + setAlarmMsg(sStandNo, sClsgn, "1", "PDC발부 전 PushBack 진행중 입니다."); + + } + + + } + + standSttusList = serviceList.get(0); + + for(int idx=0; idx 0) return; + + AlarmMsgVO alarmMsg = new AlarmMsgVO(); + alarmMsg.setAlarm_ty(sAlarmTy); + alarmMsg.setAnals_ty("13"); + alarmMsg.setArea_type("AF03006"); + alarmMsg.setArea_id(sStandNo); + alarmMsg.setTrgt_ty1("1"); + alarmMsg.setTrgt_id1(sClsgn); + alarmMsg.setAnals_msg(sAlarmMsg); + alarmMsg.setStart_end("Start"); + alamMsgQ.offer(alarmMsg); + + } + + // 주기장 알림 상황 분석(상황종료) + public void analysis_Stand_sttus_alarm_end() throws InterruptedException{ + + if( serviceList == null || serviceList.size() == 0 || alamEndChkList == null ||alamEndChkList.size() == 0 ) { + + Thread.sleep(1000); + return; + } + + // int alarmYn = 0; + // for(int k=0; k map_stand_sttus; + + DateTimeFormatter df_Pattern = DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS"); + + LocalDateTime dt; + + LinkedBlockingQueue recvVideoQ; + private DataLoadDTO dto; + Map> serviceList; + + private Integer scvQcount; + Queue alamMsgQ; + + HashMap testStandStsMap; + + HashMap testStandStsMapAI; + + public AnalysisStandStatus(LinkedBlockingQueue recvVideoQ, DataLoadDTO dataLoadDTO, Map> serviceList, Queue alamMsgQ, + HashMap testStandStsMap, + HashMap testStandStsMapAI + ){ + this.recvVideoQ =recvVideoQ; + this.dto = dataLoadDTO; + this.serviceList = serviceList; + this.alamMsgQ = alamMsgQ; + this.testStandStsMap = testStandStsMap; + this.testStandStsMapAI = testStandStsMapAI; + + initialize(); + } + + public void initialize() { + try { + + cThread_Maping_CctvIDStandNo = new CustomThread("mapingCctvStand", this, CustomThread.NO_SLEEP, this::init_map_stand_sttus, null, false); + cThread_Make_Map_StandSttus = new CustomThread("makeMapStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Ai_Video_Meta, null, false); + cThread_Analyze_StandSttus = new CustomThread("analysisStandSttus", this, CustomThread.NO_SLEEP, this::analysis_Stand_Sttus, null, false); + + map_stand_sttus = new LinkedHashMap(); + + } catch (Exception e) { + logger.error("Start Fail: "+ e.toString()); + } + } + + public void start() { + try { + + cThread_Maping_CctvIDStandNo.start(); + //cThread_Make_Map_StandSttus.start(); + cThread_Analyze_StandSttus.start(); + + + } catch (Exception e) { + logger.error("Start Fail: "+ e); + } + } + +////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /* + * Kafka를 통해 수신받은 AI Video Meta(주기장상황분석정보) 데이터 분석 + * Param : cctv List, AI Meta Data + * Return : LinkedHashMap Map_Stand_sttus + */ + private void analysis_Ai_Video_Meta() throws InterruptedException{ + + if(dto.getDb_CctvList().size() == 0 || recvVideoQ.size() == 0 || map_stand_sttus == null ||map_stand_sttus.size() == 0) { + + Thread.sleep(3000); + return ; + } + + AiAnalyzeStandSttus aiStandSttus; + + int queSize = recvVideoQ.size(); + + for(int idx = 0; idx(); + + for(DataLoadHashMap cctv : dto.getDb_CctvList()){ + + sStandNo = cctv.getItemString("STAND_NO"); + sCctv = cctv.getItemString("CCTV_ID"); + + if(map_stand_sttus.isEmpty() || map_stand_sttus.get(sCctv) == null){ + map_stand_sttus.put(sCctv, new RestServiceData(sStandNo, sCctv)); + } + } + + if(map_stand_sttus.size() != 0){ + logger.info("Stand Sttus HashMap 생성."); + }else{ + logger.info("Stand Sttus HashMap 생성 실패."); + } + + Thread.sleep(1000 * (60 * 10)); // 10분 + } + + private int analysis_Stand_Sttus_Arr() { + + if(map_stand_sttus.size() == 0 || dto.getDb_FltArr().size() == 0) return 0; + + String sCctv, sStandNo, sSttusCD; + int idx; + + List list_arr = dto.getDb_FltArr(); + + + // 도착예정정보 확인 + // for(DataLoadHashMap fltarr : list_arr){ + for(idx = 0; idx < list_arr.size(); idx++){ + + DataLoadHashMap _mfltarr = list_arr.get(idx); + + sSttusCD = "0"; + + sStandNo = _mfltarr.getItemString("STAND_NO"); + + // logger.info("fltarr : " + fltarr.toString()); + //logger.info("ARR-Stand : " + sStandNo); + + sCctv = findCctvID(sStandNo); + + if(sCctv.equals("")){ + logger.error("cctv ID Not find : " + sStandNo); + continue; + } + + /* [1]도착예정 + * - 출발 진행중이 이님. + * - 1순위 : 접근관제 인지 시각이 있음 + * - 2순위 : 활주로 도착시각이 있음 + */ + + if( !_mfltarr.getItemString("APP_IN_DT").equals("") || !_mfltarr.getItemString("ACTL_ARR_DT").equals("")){ + + sSttusCD = "1"; + + }else{ + sSttusCD = "0"; + } + + map_stand_sttus.get(sCctv).setClsgn(_mfltarr.getItemString("CLSGN")); + map_stand_sttus.get(sCctv).setStand_sttus_ty(sSttusCD); + + // logger.info("ARR --- StandNo:"+sStandNo + "|" + "cctv:" +sCctv + "|" + "CallSign:"+fltarr.get("CLSGN") + " ["+fltarr.toString()+"]"); + } + + // if(idx > 0 ) logger.info("도착 주기장 :" + (idx +1) + "건 갱신" ); + + return idx; + + } + + private int analysis_Stand_Sttus_Dep() { + + if(map_stand_sttus.size() == 0 || dto.getDb_FltDep().size() == 0) return 0; + + String sCctv, sStandNo, sSttusCD; + int idx; + int iDepStandTm = 15; + + List list_Dep = dto.getDb_FltDep(); + + //출발 스케줄 확인 + // for(DataLoadHashMap fltdep : dto.getDb_FltDep()){ + for(idx = 0; idx < list_Dep.size(); idx++ ){ + + DataLoadHashMap _mfltdep = list_Dep.get(idx); + + /* [2]PDC발부 전 + * - 예상 주기장 출발 시각 15분 이내. + * - 실제 주기장 출발 시간이 없음. + * - PDC발부 시각이 없음. + */ + + /* [3]PDC발부 + * - 예상 주기장 출발 시각 15분 이내. + * - 실제 주기장 출발 시간이 없음. + * - PDC발부 시각이 있음. + */ + + /* [4]PUSH-BACK 대기 + * - 예상 주기장 출발 시각 15분 이내. + * - 실제 주기장 출발 시간이 없음. + * - PDC발부 시각이 있음. + * - 출발 승인 대기 시각이 있음(ACTL_CLR_WAIT_DT) + */ + + /* [5]PUSH-BACK 진행 + * - 실제 주기장 출발 시간이 있음 + * - A-CDM 상태코드 'TAX' 미수신 + */ + + /* [9]PUSH-BACK 종료 + * - 실제 주기장 출발 시간이 있음 + * - A-CDM 상태코드 'TAX'가 수신됨 + */ + + sSttusCD = "0"; + + sStandNo = _mfltdep.getItemString("STAND_NO"); + + sCctv = findCctvID(sStandNo); + + if(sCctv.equals("")){ + logger.error("cctv ID Not find : " + sStandNo); + continue; + } + + String sRecvTime = _mfltdep.getItemString("EXP_STAND_OFF_DT"); + sRecvTime = sRecvTime.concat("00.000"); + dt = LocalDateTime.parse(sRecvTime, df_Pattern); + + Duration diff = Duration.between(LocalDateTime.now(), dt); + + String aiSttus; + + sSttusCD = "0"; + aiSttus = map_stand_sttus.get(sCctv).getAiStandSttus().getArcft_stand(); + + // 예상 주기장 출발 시각 15분 이내, 실제 주기장 출발 시간이 없음. + // if( aiSttus.equals("Y")){ //AI 상황분석 검증 완료전까지 주석 + + if(_mfltdep.getItemString("ACTL_STAND_OFF_DT").equals("")){ + + if(_mfltdep.getItemString("PDC_ISUE_TM").equals("")){ + sSttusCD = "2"; //[2]PDC발부 전 + }else{ + sSttusCD = "3"; //[3]PDC발부 + } + + if( !_mfltdep.getItemString("ACTL_CLR_WAIT_DT").equals("")){ + sSttusCD = "4"; //[4]PUSH-BACK 대기 + } + } + + if( !_mfltdep.getItemString("ACTL_STAND_OFF_DT").equals("")){ + + sSttusCD = "5"; //[5]PUSH-BACK 진행 + + if(_mfltdep.getItemString("TAX_YN").equals("Y")){ + sSttusCD = "6"; //[9]PUSH-BACK 종료 + } + } + + // }else{ + // sSttusCD = "0"; + // } + + map_stand_sttus.get(sCctv).setClsgn(_mfltdep.getItemString("CLSGN")); + map_stand_sttus.get(sCctv).setStand_sttus_ty(sSttusCD); + + // logger.info("DEP --- StandNo:"+sStandNo + "|" + "cctv:" +sCctv + "|" + "CallSign:"+fltdep.get("CLSGN") + " ["+fltdep.toString()+"]"); + } + + + // if(idx > 0 ) logger.info("출발 주기장 :" + (idx +1) + "건 갱신" ); + + return idx; + } + + private void analysis_Stand_Sttus() throws InterruptedException { + + if(recvVideoQ.size() == 0){ + // logger.info("AI Video Mata Data(Kafka) 수신 대기"); + Thread.sleep(3000); + return ; + } + + analysis_Ai_Video_Meta(); + + + + int anaCnt; + + analysis_Stand_Sttus_Arr(); + + analysis_Stand_Sttus_Dep(); + + + + // test Map의 주기장 번호가 있을때 + if(testStandStsMap.size() > 0){ + + for( String testStand : testStandStsMap.keySet()){ + + String sCctvID = findCctvID(testStand); + + if(!sCctvID.equals("")){ + map_stand_sttus.get(sCctvID).setStand_sttus_ty("1"); + map_stand_sttus.get(sCctvID).setStand_sttus_ty(testStandStsMap.get(testStand)); + } + + + } + + } + + if(testStandStsMapAI.size() > 0){ + + for( String testStand : testStandStsMapAI.keySet()){ + + String sCctvID = findCctvID(testStand); + + if(!sCctvID.equals("")){ + + AiAnalyzeStandSttus aists = new AiAnalyzeStandSttus(); + String[] arrTestSts = testStandStsMapAI.get(testStand); + + + aists.setArcft_stand(arrTestSts[0]); + aists.setBrdg_cnnctd(arrTestSts[1]); + aists.setCrg_dr_opnd(arrTestSts[2]); + aists.setPad_clear(arrTestSts[3]); + aists.setTwng_cr_cnnctd(arrTestSts[4]); + + map_stand_sttus.get(sCctvID).setAiStandSttus(aists); + + } + + + } + + + } + + + // 서비스큐 데이터 적재 + store_Service_Data(); + + Thread.sleep(300); + } + + private void store_Service_Data(){ + + if(map_stand_sttus.size() == 0 ) return ; + + LinkedList valueList = new LinkedList(map_stand_sttus.values()); + + for(int qi=0; qi recvVideoQ; + private Queue alamMsgQ; + private Map> serviceList; + private boolean serviceRunnig; + + public QueueManageBean(){ + this.recvVideoQ = new LinkedBlockingQueue(); + this.alamMsgQ = new LinkedBlockingQueue(); + this.serviceList = new HashMap>(); + this.serviceRunnig = false; + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/config/ServiceConfig.java b/src/main/java/kr/gmtc/gw/standstatus/config/ServiceConfig.java new file mode 100644 index 0000000..56e3421 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/config/ServiceConfig.java @@ -0,0 +1,77 @@ +package kr.gmtc.gw.standstatus.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import kr.gmtc.gw.comp.rest.vo.RestServiceData; +import kr.gmtc.gw.standstatus.database.dto.DataLoadDTO; +import kr.gmtc.gw.standstatus.kafka.vo.AiVideoMetaData; +import kr.gmtc.gw.standstatus.vo.AlarmMsgVO; + +import javax.annotation.PostConstruct; + +import java.lang.reflect.Array; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +@Configuration("ServiceConfig") +public class ServiceConfig { + + @Value("${root}") + private String root; + + @PostConstruct + private void initialize() { + } + + @Bean(name = "dataLoadDTO") + public DataLoadDTO dataLoadDTO(){ + return new DataLoadDTO(); + } + + @Bean(name = "recvVideoQ") + public LinkedBlockingQueue recvVideoQ(){ + return new LinkedBlockingQueue(); + } + + @Bean(name = "alamMsgQ") + public Queue alamMsgQ(){ + return new LinkedBlockingQueue(); + } + + @Bean(name = "alamEndChkList") + public LinkedList alamEndChkList(){ + return new LinkedList(); + } + + @Bean(name = "serviceList") + public Map> serviceList(){ + return new HashMap>(); + } + + @Bean(name = "serviceRunnig") + public boolean serviceRunnig(){ + return false; + } + + // @Bean(name = "queueManageBean") + // public QueueManageBean queueManageBean(){ + // return new QueueManageBean(); + // } + + @Bean(name = "testStandStsMap") + public HashMap testStandStsMap(){ + return new LinkedHashMap(); + } + + @Bean(name = "testStandStsMapAI") + public HashMap testStandStsMapAI(){ + return new LinkedHashMap(); + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/controller/MainController.java b/src/main/java/kr/gmtc/gw/standstatus/controller/MainController.java new file mode 100644 index 0000000..de6f40d --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/controller/MainController.java @@ -0,0 +1,155 @@ +package kr.gmtc.gw.standstatus.controller; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextClosedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import kr.gmt.so.state.StateManager; +import kr.gmtc.gw.comp.rest.ServiceQueManager; +import kr.gmtc.gw.comp.rest.vo.RestServiceData; +import kr.gmtc.gw.comp.thread.CustomThread; +import kr.gmtc.gw.standstatus.component.AnalysisStandStatus; +import kr.gmtc.gw.standstatus.config.QueueManageBean; +import kr.gmtc.gw.standstatus.database.datasource1.CmSelectDao; +import kr.gmtc.gw.standstatus.database.datasource2.IcSelectDao; +import kr.gmtc.gw.standstatus.database.dto.DataLoadDTO; +import kr.gmtc.gw.standstatus.kafka.vo.AiVideoMetaData; +import kr.gmtc.gw.standstatus.service.DataLoadService; +import kr.gmtc.gw.standstatus.vo.AlarmMsgVO; + +@Component("controller") +public class MainController implements ApplicationListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private ServiceQueManager serviceQueManager; + + + @Resource(name = "cmSelectDao") + private CmSelectDao cmSelectDao; + + @Resource(name = "icSelectDao") + private IcSelectDao icSelectDao; + + @Resource(name = "dataLoadDTO") + private DataLoadDTO dataLoadDTO; + + // @Resource(name = "queueManageBean") + // private QueueManageBean queBean; + + @Resource(name = "recvVideoQ") + LinkedBlockingQueue recvVideoQ; + + @Resource(name = "serviceList") + Map> serviceList; + + @Resource(name = "alamMsgQ") + Queue alamMsgQ; + + @Resource(name = "serviceRunnig") + private boolean serviceRunnig = false; + + + @Value("${rest.service.queueCount}") + private Integer scvQcount; + + @Value("${rest.service.clearQ.maxCount}") + private Integer scvQmaxCount; + + @Value("${rest.service.clearQ.diffTime}") + private Integer scvQdiffTime; + + @Value("${rest.service.clearQ.clearTime}") + private Integer scvQclearTime; + + @Resource(name = "testStandStsMap") + HashMap testStandStsMap; + + @Resource(name = "testStandStsMapAI") + HashMap testStandStsMapAI; + + + private DataLoadService dataLoadService; + private AnalysisStandStatus analysisStatusService; + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + @Order(3) + @EventListener(ApplicationReadyEvent.class) + public void initialize() { + try { + + Marker interesting = MarkerFactory.getMarker("INTERESTING"); + + logger.info(interesting, "MarkerTest"); + + serviceQueManager = new ServiceQueManager(serviceList, serviceRunnig); + serviceQueManager.setScvQclearTime(scvQclearTime); + serviceQueManager.setScvQcount(scvQcount); + serviceQueManager.setScvQdiffTime(scvQdiffTime); + serviceQueManager.setScvQmaxCount(scvQmaxCount); + + dataLoadService = new DataLoadService(dataLoadDTO, cmSelectDao, icSelectDao); + + analysisStatusService = new AnalysisStandStatus(recvVideoQ, dataLoadDTO, serviceList, alamMsgQ, testStandStsMap, testStandStsMapAI); + analysisStatusService.setScvQcount(scvQcount); + + } catch (Exception e) { + logger.error("Start Fail: "+ e.toString()); + } + } + + @Order(4) + @EventListener(ApplicationReadyEvent.class) + public void start() { + try { + + serviceQueManager.start(); + // serviceQueManager.join(); + + dataLoadService.start(); + + Thread.sleep(2000); + analysisStatusService.start(); + + } catch (Exception e) { + logger.error("Start Fail: "+ e); + } + + } + + @Override + public void onApplicationEvent(ContextClosedEvent event) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'onApplicationEvent'"); + } + + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + private void logging_Que() { + + // logger.info("Que size:" + recvVideoQ.size()); + + // recvVideoQ.clear(); + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/controller/StandSttusServiceController.java b/src/main/java/kr/gmtc/gw/standstatus/controller/StandSttusServiceController.java new file mode 100644 index 0000000..1e9a3f4 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/controller/StandSttusServiceController.java @@ -0,0 +1,227 @@ +package kr.gmtc.gw.standstatus.controller; + +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.gw.comp.rest.vo.RestServiceHeader; +import kr.gmtc.gw.comp.rest.vo.RestServiceVO; +import kr.gmtc.gw.comp.rest.vo.RestServiceData; +import kr.gmtc.gw.standstatus.utils.CmmnUtil; + +@RestController +public class StandSttusServiceController { + + protected Logger logger; + protected ObjectMapper mapper; + + @Resource(name = "serviceList") + public Map> serviceList; + + @Resource(name = "serviceRunnig") + private boolean serviceRunnig = false; + + @Value("${rest.service.queueCount}") + private Integer scvQcount; + + @Value("${rest.service.serviceCount}") + private Integer scvDatacount; + + @Resource(name = "testStandStsMap") + HashMap testStandStsMap; + + @Resource(name = "testStandStsMapAI") + HashMap testStandStsMapAI; + + private RestServiceVO restServiceVO; + + DateTimeFormatter dfPattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + + public StandSttusServiceController(){ + logger = LoggerFactory.getLogger(this.getClass()); + mapper = new ObjectMapper(); + } + + @GetMapping(value = "/getStandStatus/{qid}", produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity getASDE( @PathVariable Integer qid) { + + int qidx = qid -1; + String sRetJsonData = ""; + + synchronized(serviceList.get(qidx)){ + sRetJsonData = makeServiceData(qidx, serviceList.get(qidx)); + } + + + return ResponseEntity.ok(sRetJsonData); + } + + + private String makeServiceData(int queIdx, Queue procQue){ + + String sendCode, sendMsg ; + RestServiceHeader jsonHeader = new RestServiceHeader(); + List jsonData = new ArrayList(); + + sendCode = "200"; + sendMsg = "----------------------------------------------------------------------------------------------------"; + + restServiceVO = new RestServiceVO(); + + int qTotalSize = procQue.size(); + int qSize = qTotalSize; + + if(qSize > scvDatacount) qSize = scvDatacount; + + if(queIdx > scvQcount -1 || queIdx < 0) { + sendCode = "Err-01"; + sendMsg = "할당되지 않은 큐를 지정했습니다."; + logger.error(sendMsg); + }else { + //if(procQue.peek() == null) { + if(qSize <= 0) { + sendCode = "200"; + sendMsg = "전송할 데이터 없음."; + // logger.error("procQue size" + " / " + procQue.size()); + }else{ + + serviceRunnig = true; + + while (qSize > 0 ) { + + RestServiceData data = procQue.poll(); + + if( data != null){ + jsonData.add(data); + } + + qSize--; + } + + serviceRunnig = false ; + } + + } + + jsonHeader.setResult_code(sendCode); + jsonHeader.setResult_msg(sendMsg); + + restServiceVO.setHeader(jsonHeader); + + if (sendCode.equals("200")) { + + restServiceVO.setData(jsonData); + + logger.info("Que["+(queIdx + 1)+"] service count :" + jsonData.size() + "/" + qTotalSize); + } + + String sRetJsonData = ""; + + try { + sRetJsonData = mapper.writeValueAsString(restServiceVO); + } catch (JsonProcessingException e) { + logger.error("[AsdeServiceController] makeServiceData-JsonProcessingException : " + CmmnUtil.getStatckTrace(e)); + } + + return sRetJsonData; + + } + + @RequestMapping(value={"setStandSts/{stadNo}/{sid}"}, method=RequestMethod.GET) + public String setStandSts(@PathVariable String stadNo, @PathVariable String sid) throws Exception { + + String sStandNo, sSID ; + String retValue = ""; + + sStandNo = stadNo; + sSID = sid; + + if(Integer.parseInt(sSID) < 1 || Integer.parseInt(sSID) > 8) { + retValue = "Err: 주기장 상태의 범위는 1 ~ 6까지 입니다." ; + return retValue; + } + + testStandStsMap.put(sStandNo, sSID); + + for ( String stand : testStandStsMap.keySet() ) { + retValue = retValue + "StandNO : " + stand +", Status : " + testStandStsMap.get(stand) + "
" ; + } + + //gateStatusService.gateStatusSchedule(); + + return retValue; + } + + @RequestMapping(value={"setStandStsAI/{stadNo}/{sid}/{sAiSts}"}, method=RequestMethod.GET) + public String setStandStsAI(@PathVariable String stadNo, @PathVariable String sid, @PathVariable String[] sAiSts) throws Exception { + + String sStandNo, sSID ; + String retValue = ""; + String[] arrAiSts = {"N", "N", "N", "Y", "N"}; + + sStandNo = stadNo; + sSID = sid; + + if(sid.equals("0")){ + + }else{ + if(Integer.parseInt(sSID) < 1 || Integer.parseInt(sSID) > 8) { + retValue = "Err: 주기장 상태의 범위는 1 ~ 6까지 입니다." ; + return retValue; + } + + testStandStsMap.put(sStandNo, sSID); + + for ( String stand : testStandStsMap.keySet() ) { + retValue = retValue + "StandNO : " + stand +", Status : " + testStandStsMap.get(stand) + "
" ; + } + + } + + + if(sAiSts == null ) sAiSts = arrAiSts; + + testStandStsMapAI.put(sStandNo, sAiSts); + + for ( String stand : testStandStsMapAI.keySet() ) { + retValue = retValue + "AI Status StandNO : " + stand +", Status : " + Arrays.deepToString( testStandStsMapAI.get(stand)) + "
" ; + } + + //gateStatusService.gateStatusSchedule(); + + return retValue; + } + + @GetMapping("/setTestClear") + public String getStandStatus() throws Exception { + + testStandStsMap.clear(); + testStandStsMapAI.clear(); + //gateStatusService.gateStatusSchedule(); + + return "Test Map Clear."; + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/config/DataSourceConfigDB1.java b/src/main/java/kr/gmtc/gw/standstatus/database/config/DataSourceConfigDB1.java new file mode 100644 index 0000000..7c58856 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/config/DataSourceConfigDB1.java @@ -0,0 +1,56 @@ +package kr.gmtc.gw.standstatus.database.config; + +import javax.sql.DataSource; + + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +@Configuration +@MapperScan(value = "kr.gmtc.gw.standstatus.database.datasource1", sqlSessionFactoryRef = "factory") +public class DataSourceConfigDB1 { + + @Bean(name = "datasource") + @ConfigurationProperties(prefix = "database.db1.datasource") + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "factory") + public SqlSessionFactory sqlSessionFactory(@Qualifier("datasource") DataSource dataSource) throws Exception { + SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); + sqlSessionFactory.setDataSource(dataSource); + + org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration(); + config.setCallSettersOnNulls(true); + + Resource[] res = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db1/*.xml"); + sqlSessionFactory.setMapperLocations(res); + + sqlSessionFactory.setConfiguration(config); + + return sqlSessionFactory.getObject(); + } + + @Bean(name="SqlSessionTemplate") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("factory") SqlSessionFactory sqlSessionFactory) throws Exception{ + return new SqlSessionTemplate(sqlSessionFactory); + } + + @Bean + public DataSourceTransactionManager ATransactionManager(@Qualifier("datasource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/config/DataSourceConfigDB2.java b/src/main/java/kr/gmtc/gw/standstatus/database/config/DataSourceConfigDB2.java new file mode 100644 index 0000000..a83efe1 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/config/DataSourceConfigDB2.java @@ -0,0 +1,54 @@ +package kr.gmtc.gw.standstatus.database.config; + +import javax.sql.DataSource; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +@Configuration +@MapperScan(value = "kr.gmtc.gw.standstatus.database.datasource2", sqlSessionFactoryRef = "factory_db2") +public class DataSourceConfigDB2 { + + @Bean(name = "datasource2") + @ConfigurationProperties(prefix = "database.db2.datasource") + public DataSource dataSource2() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "factory_db2") + public SqlSessionFactory sqlSessionFactory(@Qualifier("datasource2") DataSource dataSource2) throws Exception { + SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); + sqlSessionFactory.setDataSource(dataSource2); + + org.apache.ibatis.session.Configuration config = new org.apache.ibatis.session.Configuration(); + config.setCallSettersOnNulls(true); + + Resource[] res = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/db2/*.xml"); + sqlSessionFactory.setMapperLocations(res); + + sqlSessionFactory.setConfiguration(config); + + return sqlSessionFactory.getObject(); + } + + @Bean(name="SqlSessionTemplate_db2") + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("factory_db2") SqlSessionFactory sqlSessionFactory) throws Exception{ + return new SqlSessionTemplate(sqlSessionFactory); + } + + @Bean + public DataSourceTransactionManager BTransactionManager(@Qualifier("datasource2") DataSource dataSource2) { + return new DataSourceTransactionManager(dataSource2); + } + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/datasource1/CmSelectDao.java b/src/main/java/kr/gmtc/gw/standstatus/database/datasource1/CmSelectDao.java new file mode 100644 index 0000000..2050bbd --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/datasource1/CmSelectDao.java @@ -0,0 +1,20 @@ +package kr.gmtc.gw.standstatus.database.datasource1; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap; + +@Service +public class CmSelectDao { + private CmSelectMepper cmSelectMepper; + + public CmSelectDao(CmSelectMepper cmSelecMepper){ + this.cmSelectMepper = cmSelecMepper; + } + + public List selectCctv_List(){ + return cmSelectMepper.selectCctv_List(); + } +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/datasource1/CmSelectMepper.java b/src/main/java/kr/gmtc/gw/standstatus/database/datasource1/CmSelectMepper.java new file mode 100644 index 0000000..3527f96 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/datasource1/CmSelectMepper.java @@ -0,0 +1,15 @@ +package kr.gmtc.gw.standstatus.database.datasource1; + +import java.util.List; + +import org.apache.ibatis.annotations.Mapper; + +import kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap; + +@Mapper +public interface CmSelectMepper { + + List selectCctv_List(); + +} + diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/datasource2/IcSelectDao.java b/src/main/java/kr/gmtc/gw/standstatus/database/datasource2/IcSelectDao.java new file mode 100644 index 0000000..036d688 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/datasource2/IcSelectDao.java @@ -0,0 +1,30 @@ +package kr.gmtc.gw.standstatus.database.datasource2; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap; + + +@Service +public class IcSelectDao { + private IcSelectMepper icSelectMepper; + + public IcSelectDao(IcSelectMepper icSelectMepper){ + this.icSelectMepper = icSelectMepper; + } + + public List select_flt_dep(){ + return icSelectMepper.select_flt_dep(); + } + + public List select_flt_arr(){ + return icSelectMepper.select_flt_arr(); + } + + public int getAnalsIdSeq(){ + return icSelectMepper.getAnalsIdSeq(); + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/datasource2/IcSelectMepper.java b/src/main/java/kr/gmtc/gw/standstatus/database/datasource2/IcSelectMepper.java new file mode 100644 index 0000000..81b6160 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/datasource2/IcSelectMepper.java @@ -0,0 +1,16 @@ +package kr.gmtc.gw.standstatus.database.datasource2; + +import java.util.List; + +import org.apache.ibatis.annotations.Mapper; + +import kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap; + +@Mapper +public interface IcSelectMepper { + + List select_flt_dep(); + List select_flt_arr(); + int getAnalsIdSeq(); + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/dto/DataLoadDTO.java b/src/main/java/kr/gmtc/gw/standstatus/database/dto/DataLoadDTO.java new file mode 100644 index 0000000..6b99620 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/dto/DataLoadDTO.java @@ -0,0 +1,18 @@ +package kr.gmtc.gw.standstatus.database.dto; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class DataLoadDTO { + + private List db_CctvList; + private List db_FltDep; + private List db_FltArr; + private List db_CMMN_CT019; + private List db_CMMN_CT038; + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/database/dto/DataLoadHashMap.java b/src/main/java/kr/gmtc/gw/standstatus/database/dto/DataLoadHashMap.java new file mode 100644 index 0000000..089bbc8 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/database/dto/DataLoadHashMap.java @@ -0,0 +1,23 @@ +package kr.gmtc.gw.standstatus.database.dto; + +import java.util.HashMap; + +public class DataLoadHashMap extends HashMap { + + public String getItemString(String key) { + + String data = (String) super.get( key.toUpperCase()); + + if(data == null) return data = ""; + + return data; + } + + // public int getItemNumber(String key) { + + // int data = Integer.parseInt ( (String) super.get( key.toUpperCase())); + + // return data; + // } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/config/KafkaConfig.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/config/KafkaConfig.java new file mode 100644 index 0000000..6d39654 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/config/KafkaConfig.java @@ -0,0 +1,65 @@ +package kr.gmtc.gw.standstatus.kafka.config; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.kafka.clients.consumer.ConsumerConfig; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; + +@Configuration("KafkaConfig") +public class KafkaConfig { + + @Value("${kafka.bootstrapAddress}") + private String bootstrapServers; + + @Value("${kafka.consumer.group-id}") + private String groupId; + + + @Bean + public ConsumerFactory consumerFactory(){ + + Map props = new HashMap(); + + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + props.put(ConsumerConfig.GROUP_ID_CONFIG, groupId); + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); + + return new DefaultKafkaConsumerFactory<>(props); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + return factory; + } + + @Bean + public ProducerFactory producerFactoryString() { + Map configProps = new HashMap<>(); + configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); + configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); + return new DefaultKafkaProducerFactory<>(configProps); + } + + @Bean + public KafkaTemplate kafkaTemplateString() { + return new KafkaTemplate<>(producerFactoryString()); + } + + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/consummer/KafkaMessageListener.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/consummer/KafkaMessageListener.java new file mode 100644 index 0000000..2560fe9 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/consummer/KafkaMessageListener.java @@ -0,0 +1,57 @@ +package kr.gmtc.gw.standstatus.kafka.consummer; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.LinkedBlockingQueue; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmt.so.state.StateManager; +import kr.gmtc.gw.standstatus.kafka.vo.AiVideoMetaData; +import kr.gmtc.gw.standstatus.kafka.vo.KafkaRequestVo; + +@Service +public class KafkaMessageListener { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final ObjectMapper objMapper = new ObjectMapper(); + + @Resource(name = "recvVideoQ") + LinkedBlockingQueue recvVideoQ; + + @Autowired + private StateManager stateMgr; + + @KafkaListener(topics = "${kafka.message.topic.recv.video}", groupId = "${kafka.consumer.group-id}") + public void listenAiAnalyzeVideo(@Payload String message) throws Exception{ + + if(stateMgr.isActive()){ + + try { + if (message != null) { + + KafkaRequestVo vo = objMapper.readValue(message, KafkaRequestVo.class); + recvVideoQ.add(vo.getData()); + + } + } catch(Exception e) { + logger.error(e.getMessage()); + } + } + + + } + + public String getTime() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss")); + } +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/producer/KafkaProduceStandSttus.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/producer/KafkaProduceStandSttus.java new file mode 100644 index 0000000..9f4dda8 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/producer/KafkaProduceStandSttus.java @@ -0,0 +1,121 @@ +package kr.gmtc.gw.standstatus.kafka.producer; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmt.so.state.StateManager; +import kr.gmtc.gw.comp.rest.vo.RestServiceData; +import kr.gmtc.gw.standstatus.kafka.vo.KafkaServiceData; +import kr.gmtc.gw.standstatus.kafka.vo.KafkaServiceVO; +import kr.gmtc.gw.standstatus.kafka.vo.ResponsHeader; + +@Component +public class KafkaProduceStandSttus { + + protected Logger logger; + + @Autowired + private KafkaTemplate kafkaTemplateString; + + @Resource(name = "serviceList") + public Map> serviceList; + + @Value("${kafka.message.topic.send.sttus}") + private String topicStandSttus; + + ObjectMapper mapper = new ObjectMapper(); + + @Autowired + private StateManager stateMgr; + + public KafkaProduceStandSttus(){ + logger = LoggerFactory.getLogger(this.getClass()); + } + + private KafkaServiceVO kafkaServiceVO; + + @Scheduled(fixedDelay = 1000, initialDelay = 1000) + public void sendMessage() { + + String sRetJsonData = ""; + + stateMgr.updateState(); + + if(stateMgr.isActive()){ + + logger.info("************************** serviceList Count : " + serviceList.get(2).size()); + + if(serviceList.get(2).size() > 0){ + sRetJsonData = makeServiceData(serviceList.get(2)); + } + + if(sRetJsonData != null && !sRetJsonData.equals("")){ + kafkaTemplateString.send(topicStandSttus, sRetJsonData); + } + + } + + } + + private String makeServiceData(LinkedList procQue){ + + String sendCode, sendMsg ; + ResponsHeader jsonHeader = new ResponsHeader(); + List jsonData = new ArrayList(); + + sendCode = "200"; + sendMsg = ""; + + kafkaServiceVO = new KafkaServiceVO(); + + for( RestServiceData data : procQue ){ + + KafkaServiceData cnvData = new KafkaServiceData(); + cnvData.setStand_no(data.getStand_no()); + cnvData.setClsgn(data.getClsgn()); + cnvData.setStand_sttus_ty(data.getAiStandSttus()); + cnvData.setAircraft_sttus_ty(data.getStand_sttus_ty()); + + jsonData.add(cnvData); + } + + jsonHeader.setResult_code(sendCode); + jsonHeader.setResult_msg(sendMsg); + + kafkaServiceVO.setHeader(jsonHeader); + + if (sendCode.equals("200")) { + + kafkaServiceVO.setData(jsonData); + + //logger.info("Que["+(queIdx + 1)+"] service count :" + jsonData.size() + "/" + qTotalSize); + } + + String sRetJsonData = ""; + + try { + sRetJsonData = mapper.writeValueAsString(kafkaServiceVO); + } catch (JsonProcessingException e) { + logger.error("makeServiceData-JsonProcessingException : " + e); + } + + return sRetJsonData; + + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/producer/KafkaProduceSttusAlaram.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/producer/KafkaProduceSttusAlaram.java new file mode 100644 index 0000000..131f33c --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/producer/KafkaProduceSttusAlaram.java @@ -0,0 +1,75 @@ +package kr.gmtc.gw.standstatus.kafka.producer; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +import javax.annotation.Resource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmt.so.state.StateManager; +import kr.gmtc.gw.comp.rest.vo.RestServiceData; +import kr.gmtc.gw.standstatus.component.AnalysisAlarmStatus; +import kr.gmtc.gw.standstatus.vo.AlarmMsgVO; + + +@Component +public class KafkaProduceSttusAlaram { + protected Logger logger; + + @Autowired + private KafkaTemplate kafkaTemplateString; + + @Autowired + private AnalysisAlarmStatus makeAlamMsgService; + + @Resource(name = "serviceList") + public Map> serviceList; + + @Value("${kafka.message.topic.send.alarm}") + private String topicStandSttus; + + ObjectMapper mapper = new ObjectMapper(); + + @Autowired + private StateManager stateMgr; + + public KafkaProduceSttusAlaram(){ + logger = LoggerFactory.getLogger(this.getClass()); + } + + //private KafkaServiceVO kafkaServiceVO; + @Resource(name = "alamMsgQ") + Queue alamMsgQ; + + @Scheduled(fixedDelay = 1000, initialDelay = 1000) + public void sendMessage() { + + if(stateMgr.isActive()){ + + logger.info("************************** alamMsgQ Count : " + alamMsgQ.size()); + + String sRetJsonData = ""; + + if(alamMsgQ.size() > 0) + sRetJsonData = makeAlamMsgService.makeAlamMsg(); + + if(sRetJsonData != null && !sRetJsonData.equals("")){ + kafkaTemplateString.send(topicStandSttus, sRetJsonData); + } + } + + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/AiVideoMetaData.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/AiVideoMetaData.java new file mode 100644 index 0000000..bf66147 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/AiVideoMetaData.java @@ -0,0 +1,29 @@ +package kr.gmtc.gw.standstatus.kafka.vo; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class AiVideoMetaData { + + private String cc_id; + private String arcrft_tp; + private String arcrft_yn; + private String arln; + private String brdg_cnnctd; + private String crg_dr_opnd; + private String pad_clear; + private String twng_cr_cnnctd; + private String zn_id; + + private String arcrft_dtct_tm; + private String arcrft_sv_tm; + private String brdg_cnnctd_dtct_tm; + private String brdg_cnnctd_sv_tm; + private String crg_dr_opnd_dtct_tm; + private String crg_dr_opnd_sv_tm; + private String twng_cr_cnnctd_dtct_tm; + private String twng_cr_cnnctd_sv_tm; + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaRequestVo.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaRequestVo.java new file mode 100644 index 0000000..120dd99 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaRequestVo.java @@ -0,0 +1,20 @@ +package kr.gmtc.gw.standstatus.kafka.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +@JsonPropertyOrder({ "result_code", "result_msg" }) +public class KafkaRequestVo { + + @JsonProperty("header") + private ResponsHeader header; + + @JsonProperty("data") + private AiVideoMetaData data; + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaServiceData.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaServiceData.java new file mode 100644 index 0000000..646ca26 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaServiceData.java @@ -0,0 +1,17 @@ +package kr.gmtc.gw.standstatus.kafka.vo; + +import kr.gmtc.gw.standstatus.vo.AiAnalyzeStandSttus; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class KafkaServiceData { + + private String stand_no; + private String clsgn; + private AiAnalyzeStandSttus stand_sttus_ty; + private String aircraft_sttus_ty; + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaServiceVO.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaServiceVO.java new file mode 100644 index 0000000..630b426 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/KafkaServiceVO.java @@ -0,0 +1,14 @@ +package kr.gmtc.gw.standstatus.kafka.vo; + +import java.util.List; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class KafkaServiceVO { + private ResponsHeader header; + private List data; + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/ResponsHeader.java b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/ResponsHeader.java new file mode 100644 index 0000000..9f81ada --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/kafka/vo/ResponsHeader.java @@ -0,0 +1,59 @@ +package kr.gmtc.gw.standstatus.kafka.vo; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ResponsHeader implements Serializable { + + @JsonProperty("result_code") + private String result_code; + + @JsonProperty("result_msg") + private String result_msg; + + @JsonProperty("send_tm") + private String send_tm; + + public ResponsHeader(){ + super(); + + this.result_code = ""; + this.result_msg = ""; + this.send_tm = ""; + + } + + public ResponsHeader(String result_code, String result_msg) { + super(); + + this.result_code = result_code; + this.result_msg = result_msg; + this.send_tm = ""; + + } + + public String getResult_code() { + return result_code; + } + public void setResult_code(String result_code) { + this.result_code = result_code; + } + public String getResult_msg() { + return result_msg; + } + public void setResult_msg(String result_msg) { + this.result_msg = result_msg; + } + + public String getSend_tm() { + return send_tm; + } + + public void setSend_tm(String send_tm) { + this.send_tm = send_tm; + } + + + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/logger/CaptureAppender.java b/src/main/java/kr/gmtc/gw/standstatus/logger/CaptureAppender.java new file mode 100644 index 0000000..718d6d3 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/logger/CaptureAppender.java @@ -0,0 +1,74 @@ +package kr.gmtc.gw.standstatus.logger; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; +import ch.qos.logback.core.spi.FilterReply; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class CaptureAppender extends AppenderBase { + + /** + * Guard flag to prevent recursive calling of the appender. + */ + boolean guard; + + + /** + * Flag indicates that the appender is collecting the contents and storing them away + */ + + private boolean collect; + + /** + * STorage location for captured HTTP output. + */ + + private List capturedOutput = new ArrayList<>(); + + private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + @Override + protected synchronized void append(ILoggingEvent evt) + { + + if (guard) { + return; + } + + try { + guard = true; + + if (!this.started) { + return; + } + + if (getFilterChainDecision(evt) == FilterReply.DENY) { + return; + } + + capturedOutput.add(evt.getMessage()); + + } finally { + guard = false; + } + } + + public void startCollecting() { + this.collect = true; + this.capturedOutput.clear(); + } + + public List stopCollecting() { + this.collect = false; + + List immutaList = new ArrayList<>(); + immutaList.addAll(this.capturedOutput); + immutaList = Collections.unmodifiableList(immutaList); + + return immutaList; + } +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/logger/CustomAppender.java b/src/main/java/kr/gmtc/gw/standstatus/logger/CustomAppender.java new file mode 100644 index 0000000..be38298 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/logger/CustomAppender.java @@ -0,0 +1,20 @@ +package kr.gmtc.gw.standstatus.logger; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; + +public class CustomAppender extends AppenderBase { + + // private static final SimpleDateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + @Override + protected void append(ILoggingEvent iLoggingEvent) { + System.out.println(iLoggingEvent.getFormattedMessage()); + } + + @Override + public void start() { + super.start(); + } + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/logger/CustomLayout.java b/src/main/java/kr/gmtc/gw/standstatus/logger/CustomLayout.java new file mode 100644 index 0000000..1283c52 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/logger/CustomLayout.java @@ -0,0 +1,9 @@ +package kr.gmtc.gw.standstatus.logger; + + +public class CustomLayout { + + + + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/service/DataLoadService.java b/src/main/java/kr/gmtc/gw/standstatus/service/DataLoadService.java new file mode 100644 index 0000000..c9ff15d --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/service/DataLoadService.java @@ -0,0 +1,93 @@ +package kr.gmtc.gw.standstatus.service; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.gw.comp.thread.CustomThread; +import kr.gmtc.gw.standstatus.database.datasource1.CmSelectDao; +import kr.gmtc.gw.standstatus.database.datasource2.IcSelectDao; +import kr.gmtc.gw.standstatus.database.dto.DataLoadDTO; +import kr.gmtc.gw.standstatus.database.dto.DataLoadHashMap; + + +// @Service +public class DataLoadService { + + // @Resource(name = "dataLoadDTO") + private DataLoadDTO dataLoadDTO; + + // @Resource(name = "cmSelectDao") + private CmSelectDao cmSelectDao; + + // @Resource(name = "icSelectDao") + private IcSelectDao icSelectDao; + + private CustomThread threadLoadCctvList; + private CustomThread threadLoadFlt; + + private final Logger logger; + + + public DataLoadService(DataLoadDTO dataLoadDTO, CmSelectDao cmSelectDao, IcSelectDao icSelectDao){ + logger = LoggerFactory.getLogger(this.getClass()); + this.dataLoadDTO = dataLoadDTO; + this.cmSelectDao = cmSelectDao; + this.icSelectDao = icSelectDao; + + initialize(); + } + + public void initialize() { + try { + + threadLoadCctvList = new CustomThread("loadCctvList", this, CustomThread.NO_SLEEP, this::loadCctvList, null, false); + + threadLoadFlt = new CustomThread("loadArcftFlt", this, CustomThread.NO_SLEEP, this::loadArcftFltSchedule, null, false); + + } catch (Exception e) { + // logger.writeLevelLog("[MainController] Prepare Fail " + e.getMessage(), LogLevelType.LOG_ERROR, "AllLog"); + // System.exit(1); + } + } + + public void start() { + try { + + threadLoadCctvList.start(); + threadLoadFlt.start(); + + } catch (Exception e) { +// logger.writeLevelLog("[MainController] Start Fail " + e.getMessage(), LogLevelType.LOG_ERROR, "AllLog"); + // System.exit(1); + } + } + + + ////////////////////////////////////////////////////////////////////////// + + private void loadCctvList() throws InterruptedException{ + + List db_CctvList = cmSelectDao.selectCctv_List(); + + if(db_CctvList == null){ + logger.error("cctv load fail"); + }else{ + dataLoadDTO.setDb_CctvList(db_CctvList); + logger.info("cctv load Count:" + db_CctvList.size()); + } + + Thread.sleep(600000); + } + + + private void loadArcftFltSchedule() throws InterruptedException{ + + dataLoadDTO.setDb_FltDep(icSelectDao.select_flt_dep()); + dataLoadDTO.setDb_FltArr(icSelectDao.select_flt_arr()); + + Thread.sleep(30000); + } + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/utils/CmmnUtil.java b/src/main/java/kr/gmtc/gw/standstatus/utils/CmmnUtil.java new file mode 100644 index 0000000..9fef0e3 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/utils/CmmnUtil.java @@ -0,0 +1,12 @@ +package kr.gmtc.gw.standstatus.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +public class CmmnUtil { + public static String getStatckTrace(Throwable t) { + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + return sw.toString(); + } +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/vo/AiAnalyzeStandSttus.java b/src/main/java/kr/gmtc/gw/standstatus/vo/AiAnalyzeStandSttus.java new file mode 100644 index 0000000..c69ad11 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/vo/AiAnalyzeStandSttus.java @@ -0,0 +1,22 @@ +package kr.gmtc.gw.standstatus.vo; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AiAnalyzeStandSttus { + private String arcft_stand; + private String brdg_cnnctd; + private String crg_dr_opnd; + private String pad_clear; + private String twng_cr_cnnctd; + + public AiAnalyzeStandSttus(){ + this.arcft_stand = ""; + this.brdg_cnnctd = ""; + this.crg_dr_opnd = ""; + this.pad_clear = ""; + this.twng_cr_cnnctd = ""; + } +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmMsgVO.java b/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmMsgVO.java new file mode 100644 index 0000000..0f64e41 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmMsgVO.java @@ -0,0 +1,19 @@ +package kr.gmtc.gw.standstatus.vo; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class AlarmMsgVO { + private String alarm_ty; + private String anals_ty; + private String area_type; + private String area_id; + private String trgt_ty1; + private String trgt_id1; + private String trgt_ty2; + private String trgt_id2; + private String anals_msg; + private String start_end; +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmTargetVO.java b/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmTargetVO.java new file mode 100644 index 0000000..6804ad0 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmTargetVO.java @@ -0,0 +1,11 @@ +package kr.gmtc.gw.standstatus.vo; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class AlarmTargetVO { + private String trgt_ty; + private String trgt_id; +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmVO.java b/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmVO.java new file mode 100644 index 0000000..76d4ce5 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/vo/AlarmVO.java @@ -0,0 +1,18 @@ +package kr.gmtc.gw.standstatus.vo; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class AlarmVO { + private String anals_id; + private String anals_dt; + private String anals_ty; + private AreaVO area; + private AlarmTargetVO target1; + private AlarmTargetVO target2; + private String anals_msg; + private String start_end; + +} \ No newline at end of file diff --git a/src/main/java/kr/gmtc/gw/standstatus/vo/AreaVO.java b/src/main/java/kr/gmtc/gw/standstatus/vo/AreaVO.java new file mode 100644 index 0000000..c86ff38 --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/vo/AreaVO.java @@ -0,0 +1,13 @@ +package kr.gmtc.gw.standstatus.vo; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AreaVO { + + private String area_type; + private String area_id; + +} diff --git a/src/main/java/kr/gmtc/gw/standstatus/vo/StandSttusVO.java b/src/main/java/kr/gmtc/gw/standstatus/vo/StandSttusVO.java new file mode 100644 index 0000000..b7ce60c --- /dev/null +++ b/src/main/java/kr/gmtc/gw/standstatus/vo/StandSttusVO.java @@ -0,0 +1,25 @@ +package kr.gmtc.gw.standstatus.vo; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class StandSttusVO { + + private String cctv_id; + private String stand_no; + private AiAnalyzeStandSttus aiStandSttus; + private String stand_sttus_ty; + + public StandSttusVO(){ + this.aiStandSttus = new AiAnalyzeStandSttus(); + } + + public StandSttusVO(String stand_no, String cctv_id){ + this.stand_no = stand_no; + this.cctv_id = cctv_id; + this.aiStandSttus = new AiAnalyzeStandSttus(); + } + +} \ No newline at end of file diff --git a/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/src/main/resources/META-INF/additional-spring-configuration-metadata.json new file mode 100644 index 0000000..8baa7e0 --- /dev/null +++ b/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -0,0 +1,57 @@ +{"properties": [ + { + "name": "root", + "type": "java.lang.String", + "description": "A description for 'root'" + }, + { + "name": "database.db1.datasource.driver-class-name", + "type": "java.lang.String", + "description": "A description for 'database.db1.datasource.driver-class-name'" + }, + { + "name": "database.db1.datasource.password", + "type": "java.lang.String", + "description": "A description for 'database.db1.datasource.password'" + }, + { + "name": "database.db1.datasource.jdbcUrl", + "type": "java.lang.String", + "description": "A description for 'database.db1.datasource.jdbcUrl'" + }, + { + "name": "database.db1.datasource.username", + "type": "java.lang.String", + "description": "A description for 'database.db1.datasource.username'" + }, + { + "name": "kafka.settings", + "type": "java.lang.String", + "description": "A description for 'kafka.settings'" + }, + { + "name": "kafka.bootstrapAddress", + "type": "java.lang.String", + "description": "A description for 'kafka.bootstrapAddress'" + }, + { + "name": "kafka.consumer.group-id", + "type": "java.lang.String", + "description": "A description for 'kafka.consumer.group-id'" + }, + { + "name": "kafka.producer.key-serializer", + "type": "java.lang.String", + "description": "A description for 'kafka.producer.key-serializer'" + }, + { + "name": "kafka.producer.value-serializer", + "type": "java.lang.String", + "description": "A description for 'kafka.producer.value-serializer'" + }, + { + "name": "kafka.message.topic.video", + "type": "java.lang.String", + "description": "A description for 'kafka.message.topic.video'" + } +]} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..a939dc5 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,125 @@ +spring: + profiles: + active: default + group: + default: + - winTest + +--- +spring: + config: + activate: + on-profile: default + +server: + port: 18083 + +rest: + service: + queueCount: 3 + serviceCount: 5000 + clearQ: + maxCount: 20000 # 1만건 + diffTime: 10000 # 10 sec + clearTime: 60000 # milli-Sec, 1분 + +state: + # 공통코드 CT001의 코드 6자리 + id: IC0302 # 주기장 상태 분석 + # 1:Primary, 2:Secondary + type: Primary + +--- +spring: + config: + activate: + on-profile: real + +root: /home/gmt/app/EyeGW_AsdeRecv + +state: + # 공통코드 CT001의 코드 6자리 + id: IC0302 # 주기장 상태 분석 + # 1:Primary, 2:Secondary + type: Primary + +--- +spring: + config: + activate: + on-profile: winTest + +root: D:\Workspace\Odroid_repository\EyeGW_Dev + +state: + # 공통코드 CT001의 코드 6자리 + id: IC0302 # 주기장 상태 분석 + # 1:Primary, 2:Secondary + type: Primary + +database: + db1: + datasource: + driver-class-name: com.tmax.tibero.jdbc.TbDriver + jdbcUrl: jdbc:tibero:thin:@10.200.31.4:8629:sacp + username: ucm + password: ucm + db2: + datasource: + driver-class-name: com.tmax.tibero.jdbc.TbDriver + jdbcUrl: jdbc:tibero:thin:@10.200.31.4:8629:sacp + username: uic + password: uic + +kafka: + settings: + bootstrapAddress: 10.200.31.6:9091,10.200.31.8:9091,10.200.31.142:9091 + consumer: + group-id: EyeANA_StandStatus + producer: + key-serializer: org.apache.kafka.common.serialization.StringSerializer + value-serializer: org.springframework.kafka.support.serializer.JsonSerializer + message: + topic: + recv: + video: ai.analyze.video + send: + sttus: ic.analyze.stand.status + alarm: ic.analyze.alarm +--- +spring: + config: + activate: + on-profile: devServer + +root: D:\Workspace\Odroid_repository\EyeGW_Dev + +database: + db1: + datasource: + driver-class-name: com.tmax.tibero.jdbc.TbDriver + jdbcUrl: jdbc:tibero:thin:@118.220.143.174:18629:SACP_T_DB + username: ucm + password: ucm + db2: + datasource: + driver-class-name: com.tmax.tibero.jdbc.TbDriver + jdbcUrl: jdbc:tibero:thin:@118.220.143.174:18629:SACP_T_DB + username: uic + password: uic + +kafka: + settings: + bootstrapAddress: 118.220.143.175:9091,118.220.143.176:9091,118.220.143.176:9092 + consumer: + group-id: EyeANA_StandStatus + producer: + key-serializer: org.apache.kafka.common.serialization.StringSerializer + value-serializer: org.springframework.kafka.support.serializer.JsonSerializer + message: + topic: + recv: + video: ai.analyze.video + send: + sttus: ic.analyze.stand.status + alarm: ic.analyze.alarm \ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..9975b15 --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + ${LOG_PATTERN} + + + + + + + + + + INFO + + + + ${LOG_PATH}${PATH_SEPARATOR}${LOG_FILE_NAME}.log + + + + ${FILE_LOG_PATTERN} + + + + + + ${LOG_PATH}${PATH_SEPARATOR}%d{yyyyMM,aux}${PATH_SEPARATOR}%d{yyyyMMdd}.log + + 10 + + 10GB + + true + + + + + + + false + 0 + 1024 + true + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/mapper/db1/cm_sql.xml b/src/main/resources/mapper/db1/cm_sql.xml new file mode 100644 index 0000000..7842459 --- /dev/null +++ b/src/main/resources/mapper/db1/cm_sql.xml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/db2/ic_sql.xml b/src/main/resources/mapper/db2/ic_sql.xml new file mode 100644 index 0000000..df38195 --- /dev/null +++ b/src/main/resources/mapper/db2/ic_sql.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + \ No newline at end of file