diff --git a/ana/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java b/ana/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java index af4c0ce..8629f23 100644 --- a/ana/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java +++ b/ana/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java @@ -205,7 +205,7 @@ public class ParseTargetRunnable implements Runnable { sb.append(dateTime); sb.append(","); sb.append(logclassification); sb.append(","); //log구분 - sb.append(swclassification); sb.append(","); //sw구분 + sb.append("8"); sb.append(","); //sw구분 sb.append(classification); sb.append("|"); //서버구분 int i = 0; diff --git a/ana/src/main/java/kr/gmtc/tss/data/vo/StandStatusVO.java b/ana/src/main/java/kr/gmtc/tss/data/vo/StandStatusVO.java index f2e032d..b799501 100644 --- a/ana/src/main/java/kr/gmtc/tss/data/vo/StandStatusVO.java +++ b/ana/src/main/java/kr/gmtc/tss/data/vo/StandStatusVO.java @@ -23,6 +23,9 @@ public class StandStatusVO implements Comparable { @JsonProperty("aircraft_sttus_ty") private String aircraftSttusTy; //주기장 항공기 상태 타입(공통코드-CT019) private String clsgn; + private String schdul_id; + private String ac_reg_no; + @Override public String toString() { @@ -87,6 +90,22 @@ public class StandStatusVO implements Comparable { this.aircraftSttusTy = aircraftSttusTy; } + public String getSchdul_id() { + return schdul_id; + } + + public void setSchdul_id(String schdul_id) { + this.schdul_id = schdul_id; + } + + public String getAc_reg_no() { + return ac_reg_no; + } + + public void setAc_reg_no(String ac_reg_no) { + this.ac_reg_no = ac_reg_no; + } + @Override public boolean equals(Object obj) { //p1.equals(p2) diff --git a/ana/src/main/resources/application.yml b/ana/src/main/resources/application.yml index 2dadb40..8c57e3f 100644 --- a/ana/src/main/resources/application.yml +++ b/ana/src/main/resources/application.yml @@ -12,7 +12,7 @@ spring: # driver-class-name: oracle.jdbc.driver.OracleDriver # jdbc-url: jdbc:oracle:thin:@192.168.4.106:1521:GMTDB driver-class-name: com.tmax.tibero.jdbc.TbDriver - jdbc-url: jdbc:tibero:thin:@118.220.143.174:18629:SACP_T_DB + jdbc-url: jdbc:tibero:thin:@10.200.31.4:8629:sacp username: UIC password: UIC connectionTimeout: 5000 @@ -72,7 +72,7 @@ data-make-time: 10 kafka: - bootstrapServers: http://118.220.143.175:9091,http://118.220.143.176:9091,http://118.220.143.176:9092 + bootstrapServers: http://10.200.31.6:9091,http://10.200.31.8:9091,http://10.200.31.142:9091 topic: alarm: ic.analyze.situation status: ic.analyze.stand.status diff --git a/asde/lib/tibero-jdbc-7.0.0.jar b/asde/lib/tibero-jdbc-7.0.0.jar new file mode 100644 index 0000000..69b9029 Binary files /dev/null and b/asde/lib/tibero-jdbc-7.0.0.jar differ diff --git a/asde/libs/EyeGW-Core-0.0.3.jar b/asde/libs/EyeGW-Core-0.0.3.jar deleted file mode 100644 index ad35000..0000000 Binary files a/asde/libs/EyeGW-Core-0.0.3.jar and /dev/null differ diff --git a/asde/libs/tibero6-jdbc.jar b/asde/libs/tibero6-jdbc.jar deleted file mode 100644 index a84397d..0000000 Binary files a/asde/libs/tibero6-jdbc.jar and /dev/null differ diff --git a/asde/pom.xml b/asde/pom.xml index 9874643..64d393f 100644 --- a/asde/pom.xml +++ b/asde/pom.xml @@ -46,68 +46,18 @@ test - - - - - - - - - - - org.springframework.boot spring-boot-starter-webflux - - - - com.tmax.tibero - tibero-jdbc - 6.0 + com.tmax.tibero + tibero-jdbc + 7 system - ${basedir}/libs/tibero6-jdbc.jar - + ${basedir}/lib/tibero-jdbc-7.0.0.jar + kr.gmt.so @@ -124,12 +74,6 @@ ${basedir}/lib/ipworks-local-1.0.0.jar - - com.fasterxml.jackson.core diff --git a/asde/src/main/java/kr/gmtc/tss/main/MainServer.java b/asde/src/main/java/kr/gmtc/tss/main/MainServer.java index e7de4fe..d7d566f 100644 --- a/asde/src/main/java/kr/gmtc/tss/main/MainServer.java +++ b/asde/src/main/java/kr/gmtc/tss/main/MainServer.java @@ -35,12 +35,12 @@ import kr.gmt.so.state.StateManager; import kr.gmt.so.state.model.SystemState; import kr.gmtc.tss.data.DataInsertRunnable2; import kr.gmtc.tss.data.ParseTargetRunnable; -import kr.gmtc.tss.data.TargetManageRunnable; +// import kr.gmtc.tss.data.TargetManageRunnable; import kr.gmtc.tss.data.vo.AsdeTrackVO; import kr.gmtc.tss.db.BatchInsertManager; import kr.gmtc.tss.filelog.DataLogger; import kr.gmtc.tss.filelog.MessageBodyLogger; -import kr.gmtc.tss.netty.StringClient; +// import kr.gmtc.tss.netty.StringClient; import kr.gmtc.tss.sqllog.SqlLogger; import kr.gmtc.tss.util.ArrayBlockingLoggingQueue; import kr.gmtc.tss.util.FileUtil; @@ -120,10 +120,10 @@ public class MainServer implements InitializingBean { @Value("${selep-time-ms.sql-logger:50}") private long sqlLoggerSleepMs; - StringClient client; + // StringClient client; ParseTargetRunnable parserRunnable; DataLogger dataLoggerRunnable; - TargetManageRunnable targetManageRunnable; + // TargetManageRunnable targetManageRunnable; SqlLogger sqlLoggerRunnable; BatchInsertManager batchInsertManager; DataInsertRunnable2 dataInsertRunnable2; @@ -246,7 +246,7 @@ public class MainServer implements InitializingBean { // dataInsertRunnable.s; // client.isInterrupted(); logger.info("Pre destroy called!!"); - client.interrupt(); + // client.interrupt(); dataInsertRunnable2.setRunning(false); sqlLoggerRunnable.setRunning(false); parserRunnable.setRunning(false); diff --git a/asde/src/main/java/kr/gmtc/tss/status/CountStatus.java b/asde/src/main/java/kr/gmtc/tss/status/CountStatus.java index 261a012..8267b72 100644 --- a/asde/src/main/java/kr/gmtc/tss/status/CountStatus.java +++ b/asde/src/main/java/kr/gmtc/tss/status/CountStatus.java @@ -1,9 +1,5 @@ package kr.gmtc.tss.status; -import java.util.Queue; - -import kr.gmtc.tss.data.vo.SetDynamicVO; - public class CountStatus { private int rcvPos=0; diff --git a/asde/src/main/resources/log4jdbc.log4j2.properties b/asde/src/main/resources/log4jdbc.log4j2.properties deleted file mode 100644 index 5a75c58..0000000 --- a/asde/src/main/resources/log4jdbc.log4j2.properties +++ /dev/null @@ -1,3 +0,0 @@ -log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator - -log4jdbc.dump.sql.maxlinelength=0 \ No newline at end of file diff --git a/radar/.gitignore b/radar/.gitignore new file mode 100644 index 0000000..5bb4307 --- /dev/null +++ b/radar/.gitignore @@ -0,0 +1,35 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +/bin + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +/logs/ diff --git a/radar/.mvn/wrapper/maven-wrapper.jar b/radar/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..c1dd12f Binary files /dev/null and b/radar/.mvn/wrapper/maven-wrapper.jar differ diff --git a/radar/.mvn/wrapper/maven-wrapper.properties b/radar/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..b74bf7f --- /dev/null +++ b/radar/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/radar/README.md b/radar/README.md new file mode 100644 index 0000000..6182709 --- /dev/null +++ b/radar/README.md @@ -0,0 +1,2 @@ +# TSS + diff --git a/radar/lib/ipworks-local-1.0.0.jar b/radar/lib/ipworks-local-1.0.0.jar new file mode 100644 index 0000000..557d507 Binary files /dev/null and b/radar/lib/ipworks-local-1.0.0.jar differ diff --git a/radar/lib/state-spring-boot-starter-1.0.3.jar b/radar/lib/state-spring-boot-starter-1.0.3.jar new file mode 100644 index 0000000..4f5a7df Binary files /dev/null and b/radar/lib/state-spring-boot-starter-1.0.3.jar differ diff --git a/asde/lib/tibero6-jdbc.jar b/radar/lib/tibero6-jdbc.jar similarity index 100% rename from asde/lib/tibero6-jdbc.jar rename to radar/lib/tibero6-jdbc.jar diff --git a/radar/mvnw b/radar/mvnw new file mode 100644 index 0000000..8a8fb22 --- /dev/null +++ b/radar/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/radar/mvnw.cmd b/radar/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/radar/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/radar/pom.xml b/radar/pom.xml new file mode 100644 index 0000000..9cb28bd --- /dev/null +++ b/radar/pom.xml @@ -0,0 +1,152 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.8 + + + kr.gmtc + tss + 0.0.1-SNAPSHOT + fusion + TRACK fusion + + 1.8 + + 0.0.1-SNAPSHOT + true + + + + org.springframework.boot + spring-boot-starter-quartz + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 3.0.0 + + + + org.projectlombok + lombok + true + + + + + org.springframework.kafka + spring-kafka + + + + + + + + + + + + org.springframework.boot + spring-boot-starter-webflux + + + + + + + + + + + kr.gmt.so + state-spring-boot-starter + 1.0.3 + system + ${basedir}/lib/state-spring-boot-starter-1.0.3.jar + + + ipworks.local + ipworks-local-1.0.0 + system + 1.0.0 + ${basedir}/lib/ipworks-local-1.0.0.jar + + + + com.tmax.tibero + tibero-jdbc + 6.0 + system + ${basedir}/lib/tibero6-jdbc.jar + + + + + + + EyeTSS_Radar + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + org.projectlombok + lombok + + + + + + + + diff --git a/radar/src/main/java/META-INF/MANIFEST.MF b/radar/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000..59499bc --- /dev/null +++ b/radar/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/radar/src/main/java/kr/gmtc/tss/Application.java b/radar/src/main/java/kr/gmtc/tss/Application.java new file mode 100644 index 0000000..c534341 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/Application.java @@ -0,0 +1,13 @@ +package kr.gmtc.tss; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/asde/src/main/java/kr/gmtc/tss/area/MarineAreaLoader.java b/radar/src/main/java/kr/gmtc/tss/area/MarineAreaLoader.java similarity index 100% rename from asde/src/main/java/kr/gmtc/tss/area/MarineAreaLoader.java rename to radar/src/main/java/kr/gmtc/tss/area/MarineAreaLoader.java diff --git a/radar/src/main/java/kr/gmtc/tss/data/DataInsertRunnable.java b/radar/src/main/java/kr/gmtc/tss/data/DataInsertRunnable.java new file mode 100644 index 0000000..36e4bf3 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/data/DataInsertRunnable.java @@ -0,0 +1,92 @@ +package kr.gmtc.tss.data; + +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.tss.data.vo.RadarTrackVO; +import kr.gmtc.tss.db.BatchInsertManager; + +public class DataInsertRunnable implements Runnable { + + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + Queue radarQueue; +// Queue asdeTrackQueue; +// Queue asdeTrackLastQueue; +// final private int listChunkSize=100; + private boolean isRunning = false; + BatchInsertManager batchInsertManager; + private long sleepMillis; +// private int dynamicSetSize; +// private int dynamicRemoveUnitSize; + +// private Comparator comparator = Comparator.comparingLong(v -> ((LocalDateTime)v.getDateTime()).toInstant(ZoneOffset.ofHours(9)).toEpochMilli()); +// private Comparator comparator = Comparator.comparing( ,(a,b) -> a.getdattime()) +// Set dynamicSet = ConcurrentSkipListMap.n.newKeySet(10000); +// ConcurrentSkipListSet dynamicSet = new ConcurrentSkipListSet(comparator); + + public DataInsertRunnable(Queue radarQueue, BatchInsertManager batchInsertManager, long sleepMillis) { + this.radarQueue=radarQueue; + this.batchInsertManager=batchInsertManager; + this.sleepMillis=sleepMillis; + } + + @Override + public void run() { + + isRunning=true; + + while (isRunning) { + + try { + //static + RadarTrackVO [] chunkArr = getChunkStaticArr(radarQueue); + if(isRunning) { + if(chunkArr.length > 0) { + batchInsertManager.insertRadarData(chunkArr); + // batchInsertManager.insertRadarLastData(chunkArr); + } + } + + } catch (Exception e) { + e.printStackTrace(); + logger.info("[DataInsertRunnable2] Data Insert error : " ,e); + } + + sleep(sleepMillis); + + } + } + + + private RadarTrackVO [] getChunkStaticArr(Queue sqlQueue) { + int loopCnt=0; + loopCnt=sqlQueue.size(); + + RadarTrackVO [] chunkArr = new RadarTrackVO[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i]=sqlQueue.poll(); + } + return chunkArr; + } + + + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[TargetManager] sleep error : " +e.getLocalizedMessage()); + } + } + + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } + +} diff --git a/radar/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java b/radar/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java new file mode 100644 index 0000000..251e1bd --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java @@ -0,0 +1,177 @@ +package kr.gmtc.tss.data; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.tss.data.vo.RadarTrackVO; +import kr.gmtc.tss.status.CountStatus; + +public class ParseTargetRunnable implements Runnable { + private boolean flagFile; + private boolean flagDataBase; + private boolean flagDataFile; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + Queue rcvQueue; + Queue radarQueue; + Queue dataFileQueue; + Queue messageBodyQueue; + + private int rcvPos=0; + private int rcvStatic=0; + + private boolean isRunning = false; + private int listChunkSize=100; + private long sleepMillis; + + private String classification; + private String swclassification; + private String logclassification; + + public ParseTargetRunnable(Queue rcvQueue, Queue radarQueue, Queue dataFileQueue, Queue messageBodyQueue + , int listChunkSize, long sleepMillis, boolean flagFile, boolean flagDataBase, boolean flagDataFile + , String classification, String swclassification, String logclassification) { + this.rcvQueue=rcvQueue; + this.radarQueue=radarQueue; + this.dataFileQueue = dataFileQueue; + this.messageBodyQueue=messageBodyQueue; + this.listChunkSize=listChunkSize; + this.sleepMillis=sleepMillis; + this.flagFile = flagFile; + this.flagDataBase = flagDataBase; + this.flagDataFile = flagDataFile; + this.classification = classification; + this.swclassification = swclassification; + this.logclassification = logclassification; + } + + @Override + public void run() { + + isRunning=true; + + while (isRunning) { + try { + int loopCnt=0; + if(rcvQueue.size()>listChunkSize) { + loopCnt=listChunkSize; + }else { + loopCnt=rcvQueue.size(); + } + String [] chunkArr = new String[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i]=rcvQueue.poll(); + } + + for (int i = 0; i < chunkArr.length; i++) { + parseAndEnqueue(chunkArr[i]); + } + + } catch (Exception e) { + if (e.getMessage() != null) { + logger.debug("[ParseTarget] Parsing Error Message : " ,e); + } else { + logger.info("[ParserThread] Parsing Error Call Stack" ,e); + } + } + + sleep(sleepMillis); + } + } + + private void parseAndEnqueue(String result) { + try { + ArrayList histroyQueue = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + + Map convert = mapper.readValue(result, new TypeReference>() {}); + ArrayList> list = (ArrayList>) convert.get("data"); + + logger.info("수신 데이터 변환 건수 {} ", list.size()); + + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS"); + String dateTime = dateFormat.format(new Date()); + + StringBuilder sb = new StringBuilder(); + + sb.append(dateTime); sb.append(","); + sb.append(logclassification); sb.append(","); //log구분 + sb.append(swclassification); sb.append(","); //sw구분 + sb.append(classification); sb.append("|"); //서버구분 + int i = 0; + for (LinkedHashMap map : list) { + RadarTrackVO r = mapper.convertValue(map, RadarTrackVO.class); + + histroyQueue.add(r); + + if (i > 0) sb.append("^"); + + sb.append(r.getTrgtId()); sb.append(","); + sb.append(r.getRecptnDt()); sb.append(","); + sb.append(r.getLat()); sb.append(","); + sb.append(r.getLon()); sb.append(","); + sb.append(r.getSpd()); sb.append(","); + sb.append(r.getCos()); sb.append(","); + sb.append(r.getDetctCnt()); sb.append(","); + sb.append(r.getUndetctCnt()); + + i++; + } + + if(flagFile)messageBodyQueue.addAll(histroyQueue); + + if(flagDataFile)dataFileQueue.add(sb.toString()); + + if(flagDataBase) { + if (histroyQueue.size() > 0) { + if (flagDataBase) radarQueue.addAll(histroyQueue); + } + } + + } catch (Exception e) { + if (e.getMessage() != null) { + logger.debug("[ParserThread] Parsing Error Message : " + e.getMessage()); + logger.debug("",e); + } else { + logger.debug("[ParserThread] Parsing Error Packet Message :" + result); + } + e.printStackTrace(); + } + } + + + public synchronized CountStatus getCountAndSetZero() { + CountStatus countStatus = new CountStatus(rcvPos,rcvStatic); + rcvPos=0; + rcvStatic=0; + return countStatus; + } + + + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[ParseTargetRunnable] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } + +} diff --git a/asde/src/main/java/kr/gmtc/tss/data/TargetManageRunnable.java b/radar/src/main/java/kr/gmtc/tss/data/TargetManageRunnable.java similarity index 100% rename from asde/src/main/java/kr/gmtc/tss/data/TargetManageRunnable.java rename to radar/src/main/java/kr/gmtc/tss/data/TargetManageRunnable.java diff --git a/radar/src/main/java/kr/gmtc/tss/data/vo/RadarTrackVO.java b/radar/src/main/java/kr/gmtc/tss/data/vo/RadarTrackVO.java new file mode 100644 index 0000000..e16c948 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/data/vo/RadarTrackVO.java @@ -0,0 +1,166 @@ +package kr.gmtc.tss.data.vo; + +import java.sql.Date; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RadarTrackVO implements Comparable { + + private boolean inserted=false; + + public RadarTrackVO() { + } + + @JsonProperty("trgt_id") + private String trgtId; + @JsonProperty("recptn_dt") + private String recptnDt; + private double lat; + private double lon; + private double spd; + private double cos; + @JsonProperty("detct_cnt") + private int detctCnt; + @JsonProperty("undetct_cnt") + private int undetctCnt; + + + private String registerId; + private String registDt; + private String updusrId; + private String updtDt; + private boolean lstFlag; + + public boolean isInserted() { + return inserted; + } + + public void setInserted(boolean inserted) { + this.inserted = inserted; + } + + + + public String getTrgtId() { + return trgtId; + } + + public void setTrgtId(String trgtId) { + this.trgtId = trgtId; + } + + public String getRecptnDt() { + return recptnDt; + } + + public void setRecptnDt(String recptnDt) { + this.recptnDt = recptnDt; + } + + public double getLat() { + return lat; + } + + public void setLat(double lat) { + this.lat = lat; + } + + public double getLon() { + return lon; + } + + public void setLon(double lon) { + this.lon = lon; + } + + public double getSpd() { + return spd; + } + + public void setSpd(double spd) { + this.spd = spd; + } + + public double getCos() { + return cos; + } + + public void setCos(double cos) { + this.cos = cos; + } + + public String getRegisterId() { + return registerId; + } + + public void setRegisterId(String registerId) { + this.registerId = registerId; + } + + public String getRegistDt() { + return registDt; + } + + public void setRegistDt(String registDt) { + this.registDt = registDt; + } + + public String getUpdusrId() { + return updusrId; + } + + public void setUpdusrId(String updusrId) { + this.updusrId = updusrId; + } + + public String getUpdtDt() { + return updtDt; + } + + public void setUpdtDt(String updtDt) { + this.updtDt = updtDt; + } + + + + public boolean isLstFlag() { + return lstFlag; + } + + public void setLstFlag(boolean lstFlag) { + this.lstFlag = lstFlag; + } + + public int getDetctCnt() { + return detctCnt; + } + + public void setDetctCnt(int detctCnt) { + this.detctCnt = detctCnt; + } + + public int getUndetctCnt() { + return undetctCnt; + } + + public void setUndetctCnt(int undetctCnt) { + this.undetctCnt = undetctCnt; + } + + @Override + public boolean equals(Object obj) { + //p1.equals(p2) + if(obj instanceof RadarTrackVO) { + RadarTrackVO p = (RadarTrackVO)obj; + return this.hashCode()==p.hashCode(); + + } + return false; + } + + @Override + public int compareTo(RadarTrackVO o) { + return 0; + } +} diff --git a/radar/src/main/java/kr/gmtc/tss/data/vo/SetDynamicVO.java b/radar/src/main/java/kr/gmtc/tss/data/vo/SetDynamicVO.java new file mode 100644 index 0000000..b907549 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/data/vo/SetDynamicVO.java @@ -0,0 +1,109 @@ +package kr.gmtc.tss.data.vo; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; + +import kr.gmtc.tss.util.vo.DynamicVO; + +public class SetDynamicVO extends DynamicVO implements Comparable { + + private boolean inserted=false; + private String marineAreaId=""; + + public long timeStamp = LocalDateTime.now().toInstant(ZoneOffset.ofHours(9)).toEpochMilli(); + + public SetDynamicVO() { + } + + public SetDynamicVO(DynamicVO vo) { + + this.targetSensor = vo.getTargetSensor(); + this.packetID = vo.getPacketID(); + this.shipID = vo.getShipID(); + this.dateTime = vo.getDateTime(); + this.areaID = vo.getAreaID(); + this.msgType = vo.getMsgType(); + this.dataLength = vo.getDataLength(); + + setMode(vo.getMode()); + setRot(vo.getRot()); + setSog(vo.getSog()); + setPosacc(vo.getPosacc()); + + setLonInt(vo.getLonInt()); + setLatInt(vo.getLatInt()); + setLongitude(vo.getLongitude()); + setLatitude(vo.getLatitude()); + setCog(vo.getCog()); + setHeading(vo.getHeading()); + setEndflag(vo.getEndflag()); + setCommState(vo.getCommState()); + setSyncState(vo.getSyncState()); + setSlotTimeOut(vo.getSlotTimeOut()); + setSubMessage(vo.getSubMessage()); + setSlotInc(vo.getSlotInc()); + setNumberOfSlot(vo.getNumberOfSlot()); + setSlotOffSet(vo.getSlotOffSet()); + setKeepFlag(vo.getKeepFlag()); + setNaviStatus(vo.getNaviStatus()); + setSpecialManoeuve(vo.getSpecialManoeuve()); + setClassBUnit(vo.getClassBUnit()); + setClassBDisplay(vo.getClassBDisplay()); + setClassBBand(vo.getClassBBand()); + setClassBMsg22(vo.getClassBMsg22()); + setClassBDSC(vo.getClassBDSC()); + setModeFlag(vo.getModeFlag()); + setRaim(vo.getRaim()); + setIsRepeat(vo.getIsRepeat()); + setbSUTC(vo.getbSUTC()); + setbSUTCStr(vo.getbSUTCStr()); + setTimeStamp(vo.getTimeStamp()); + setmSec(vo.getmSec()); + + } + + + + + + + public String getMarineAreaId() { + return marineAreaId; + } + + public void setMarineAreaId(String marineAreaId) { + this.marineAreaId = marineAreaId; + } + + public boolean isInserted() { + return inserted; + } + + public void setInserted(boolean inserted) { + this.inserted = inserted; + } + + @Override + public int hashCode() { + return (this.getShipID()+this.getDateTime().format(DateTimeFormatter.ofPattern("yyyyMMdd"))+this.getLongitude()+this.getLatitude()).hashCode(); + } + + @Override + public boolean equals(Object obj) { + //p1.equals(p2) + if(obj instanceof SetDynamicVO) { + SetDynamicVO p = (SetDynamicVO)obj; + return this.hashCode()==p.hashCode(); + + } + return false; + } + + @Override + public int compareTo(SetDynamicVO o) { + + return this.getTimeStamp()-o.getTimeStamp(); + } + +} diff --git a/radar/src/main/java/kr/gmtc/tss/db/BatchInsertManager.java b/radar/src/main/java/kr/gmtc/tss/db/BatchInsertManager.java new file mode 100644 index 0000000..0515cab --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/db/BatchInsertManager.java @@ -0,0 +1,536 @@ +package kr.gmtc.tss.db; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Queue; + +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.tss.data.vo.RadarTrackVO; +import kr.gmtc.tss.main.MainServer; +import kr.gmtc.tss.status.CountStatus; + +public class BatchInsertManager { + + /** Logger. */ + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private SqlSessionFactory sqlSessionFactory; + private SqlSession session; + + private Queue sqlLogRadarQueue; + private Queue sqlLogRadarLastQueue; + + private int savePos=0; + private int saveLast=0; + private int saveStatic=0; + private int failPos=0; + private int failLast=0; + private int failStatic=0; + + /** + * mybatis batch insert 속도가 느려서 jdbc 객체를 직접 제어함. + * @param sqlSessionFactory + * @param dbType + */ + public BatchInsertManager(SqlSessionFactory sqlSessionFactory, Queue sqlLogRadarQueue, Queue sqlLogRadarLastQueue) { + this.sqlSessionFactory = sqlSessionFactory; + this.sqlLogRadarQueue = sqlLogRadarQueue; + this.sqlLogRadarLastQueue = sqlLogRadarLastQueue; +// this.dbType=dbType; + openSession(false); + } + + public void openSession(boolean forceOpen) { + if(session==null||forceOpen) + session = sqlSessionFactory.openSession(); + } + + public void closeSession() { + if(session!=null) + session.close(); + } + + public void insertRadarData(RadarTrackVO[] setRadarVoArr) { + insertRadarData(setRadarVoArr, true); + } + + + private void insertRadarData(RadarTrackVO[] setRadarVoArr, boolean isBatch) { + int fail = 0; + int save = 0; + if(setRadarVoArr==null || setRadarVoArr.length<1) { +// logger.error("insertDataAll - No tableList data"); + logger.debug("insertData(Batch:"+isBatch+") - no data in setRadarVoArr"); + return; + } +// Table destTable=tableList.get(0); + +// String sql = "INSERT INTO " + destTable.getName() + " (" + getInsertCols(destTable.getColumnList()) + ") " +// + "VALUES (" + getInsertValueParams(destTable.getColumnList()) + ")"; +// String tableName = "SACP_ASDE_TRACK_" + setAsdeTrackVoArr[0].getRecptnDt().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + + // 날짜 테이블 삭제 +// SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd"); +// String now_dt = format.format(setRadarVoArr[0].getRecptnDt()); + +// System.out.println("======================="); +// System.out.println(now_dt); +// System.out.println("======================="); + + //String tableName = "SACP_RADAR_TRACK_" + now_dt; + String tableName = "SACP_RADAR_TRACK"; + String sql = "INSERT INTO "+tableName+" (" + + " TRGT_ID, RECPTN_DT, LAT, LON, SPD, COS, DETCT_CNT, UNDETCT_CNT, REGISTER_ID) " + + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'SYSTEM')"; + + PreparedStatement ps=null; + Connection con=null; + try { + + con=session.getConnection(); + if(con.isClosed() || !con.isValid(1)) { + closeSession(); + openSession(true); + con=session.getConnection(); + } + con.setAutoCommit(false); + +// Statement statement = session.getConnection().createStatement(); + ps = con.prepareStatement(sql); + for (int i = 0; i < setRadarVoArr.length; i++) { + RadarTrackVO vo = setRadarVoArr[i]; + +// //입력으로 처리 +// //중복 입력 방지를 위함 + vo.setInserted(true); + + try { + ps.setString(1, vo.getTrgtId()); + ps.setString(2, vo.getRecptnDt()); + ps.setDouble(3, vo.getLat()); + ps.setDouble(4, vo.getLon()); + ps.setDouble(5, vo.getSpd()); + ps.setDouble(6, vo.getCos()); + ps.setInt(7, vo.getDetctCnt()); + ps.setInt(8, vo.getUndetctCnt()); + + ///건별 입력 + if(!isBatch) { + ps.execute(); + savePos++; + save++; + } + + } catch (Exception e) { + logger.debug("Data Insert error UseSqlLog"); + + sqlLogRadarQueue.add(vo); + failPos++; + fail++; + } + + //배치 입력 + if(isBatch) { + ps.addBatch(); + } + } + if(isBatch) { + ps.executeBatch(); + + //배치 insert는 arr 건수만큼 + savePos+=setRadarVoArr.length; + save = setRadarVoArr.length - fail; +// logger.info("savePos 건수"+savePos); + logger.info("저장 건수 {} : 실패 건수 {}", save, fail); + } else { + logger.info("저장 건수 {} : 실패 건수 {}", save, fail); + } + + con.commit(); + + + } catch (Exception e) { + logger.error("insertData(Batch:"+isBatch+") error", e); + if(isBatch) { + logger.error("Try insert row by row"); + insertRadarData(setRadarVoArr, false); + } + + } finally { + + if(ps!=null) { + try { + ps.close(); + } catch (SQLException e) { + logger.error("insertData(Batch:"+isBatch+") PreparedStatement close error",e); + } + } + if(con!=null) { + try { + con.commit(); + con.setAutoCommit(true); + } catch (SQLException e) { + logger.error("insertData(Batch:"+isBatch+") commit error",e); + } + } + } + + } + + public void insertRadarLastData(RadarTrackVO[] setRadarVoArr) { + insertRadarLastData(setRadarVoArr,true); + } + + private void insertRadarLastData(RadarTrackVO[] setRadarVoArr, boolean isBatch) { + + if(setRadarVoArr==null || setRadarVoArr.length<1) { +// logger.error("mergeDynamicLastAll - No tableList data"); + logger.debug("insertAsdeLastData(Batch:"+isBatch+") - no data in setAsdeTrackVoArr"); + return; + } +// Table destTable=tableList.get(0); +// String sql = "INSERT INTO " + destTable.getName() + " (" + getInsertCols(destTable.getColumnList()) + ") " +// + "VALUES (" + getInsertValueParams(destTable.getColumnList()) + ")"; + + String tableName = "SACP_RADAR_TRACK_LAST"; +// String sql = "MERGE INTO UTRACK."+tableName+" A" + +// " USING DUAL" + +// " ON (A.TRGT_ID = ?)" + +// " WHEN MATCHED THEN" + +// " UPDATE" + +// " SET A.RECPTN_DT = ?, A.LAT = ?, A.LON = ?, A.SPD = ?, A.COS = ?, A.UPDUSR_ID = ?, A.UPDT_DT = ?" + +// " WHEN NOT MATCHED THEN " + +// " INSERT " + +// " (A.TRGT_ID, A.RECPTN_DT, A.LAT, A.LON, A.SPD, A.COS, A.REGISTER_ID, A.REGIST_DT)" + +// " VALUES (?,?,?,?,?,?,?,?)"; + + String sql = ""; + + if(MainServer.LAST_DATA_CNT > 0) { + sql = " UPDATE " + tableName + + " SET RECPTN_DT = ?, LAT = ?, LON = ?, SPD = ?, COS = ?, UPDUSR_ID = ?, UPDT_DT = TO_TIMESTAMP(SYSDATE,'yyyyMMdd') " + + " WHERE TRGT_ID = ?"; + }else { + sql = " INSERT INTO " + tableName + + " (TRGT_ID, RECPTN_DT, LAT, LON, SPD, COS, REGISTER_ID, REGIST_DT) " + + " VALUES (?, ?, ?, ?, ?, ?, ?, TO_TIMESTAMP(SYSDATE,'yyyyMMdd'))"; + } + + PreparedStatement ps=null; + Connection con=null; + try { + + con=session.getConnection(); + if(con.isClosed() || !con.isValid(1)) { + closeSession(); + openSession(true); + con=session.getConnection(); + } + con.setAutoCommit(false); + + +// Statement statement = session.getConnection().createStatement(); + ps = con.prepareStatement(sql); + + for (int i = 0; i < setRadarVoArr.length; i++) { + RadarTrackVO vo = setRadarVoArr[i]; + //입력으로 처리 + //중복 입력 방지를 위함 + vo.setInserted(true); + + try { + if(MainServer.LAST_DATA_CNT > 0) { + ps.setString(1, vo.getRecptnDt()); + ps.setDouble(2, vo.getLat()); + ps.setDouble(3, vo.getLon()); + ps.setDouble(4, vo.getSpd()); + ps.setDouble(5, vo.getCos()); + ps.setString(6, vo.getTrgtId()); + }else { + ps.setString(1, vo.getTrgtId()); + ps.setString(2, vo.getRecptnDt()); + ps.setDouble(3, vo.getLat()); + ps.setDouble(4, vo.getLon()); + ps.setDouble(5, vo.getSpd()); + ps.setDouble(6, vo.getCos()); + ps.setString(7, vo.getRegisterId()); + } + + ///건별 입력 + if(!isBatch) { + ps.execute(); + saveLast++; + + if(MainServer.LAST_DATA_CNT == 0 ) { + MainServer.LAST_DATA_CNT = 1; + } + } + + } catch (Exception e) { + logger.debug("Data Insert error UseSqlLog"); + //sqlLogRadarLastQueue.add(vo); + failLast++; + } + + //배치 입력 + if(isBatch) { + ps.addBatch(); + } + + + } + if(isBatch) { + ps.executeBatch(); + + if(MainServer.LAST_DATA_CNT == 0 ) { + MainServer.LAST_DATA_CNT = 1; + } + + //배치 insert는 arr 건수만큼 + saveLast+=setRadarVoArr.length; + } + + con.commit(); + + + } catch (Exception e) { + logger.error("radarLast(Batch:"+isBatch+") error", e); + if(isBatch) { + logger.error("Try insert row by row"); + insertRadarLastData(setRadarVoArr, false); + } + + } finally { + + if(ps!=null) { + try { + ps.close(); + } catch (SQLException e) { + logger.error("radarLast(Batch:"+isBatch+") PreparedStatement close error",e); + } + } + if(con!=null) { + try { + con.commit(); + con.setAutoCommit(true); + } catch (SQLException e) { + logger.error("radarLast(Batch:"+isBatch+") commit error",e); + } + } + } + + } + public synchronized CountStatus getCountAndSetZero() { + CountStatus countStatus = new CountStatus(savePos, saveLast, saveStatic, failPos, failLast, failStatic); + + savePos = 0; + saveLast = 0; + saveStatic = 0; + failPos = 0; + failLast = 0; + failStatic = 0; + + return countStatus; + } + + /** + * + * 오류 발생시 건/건으로 저장할 수 있도록 수정 + * @param setDynamicVoArr + */ + /*public void insertData(SetDynamicVO[] setDynamicVoArr) { + + if(setDynamicVoArr==null || setDynamicVoArr.length<1) { +// logger.error("insertDataAll - No tableList data"); + logger.debug("insertData - no data in setDynamicVoArr"); + return; + } +// Table destTable=tableList.get(0); + + +// String sql = "INSERT INTO " + destTable.getName() + " (" + getInsertCols(destTable.getColumnList()) + ") " +// + "VALUES (" + getInsertValueParams(destTable.getColumnList()) + ")"; + + String tableName = "th_ais_" + setDynamicVoArr[0].getDateTime().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + + String sql = "INSERT INTO "+tableName +" (" + + " ship_id, recv_dt, lon_val, lat_val, sog_val, cog_val, hdg_val, rot_val, zone_id) " + + " VALUES (?, TO_TIMESTAMP(?,'yyyyMMddhh24miss'), ?, ?, ?, ?, ?, ?, ?)"; + + + PreparedStatement ps=null; + Connection con=null; + try { + + con=session.getConnection(); + if(con.isClosed() || !con.isValid(1)) { + closeSession(); + openSession(true); + con=session.getConnection(); + } + con.setAutoCommit(false); + + +// Statement statement = session.getConnection().createStatement(); + ps = con.prepareStatement(sql); + + for (int i = 0; i < setDynamicVoArr.length; i++) { + SetDynamicVO vo = setDynamicVoArr[i]; + //입력으로 처리 + //중복 입력 방지를 위함 + vo.setInserted(true); + + + try { + + ps.setString(1, vo.getShipID()); + // ps.setDate(2, vo.getDateTime()); + ps.setString(2, vo.getDateTime().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + ps.setDouble(3, vo.getLongitude()); + ps.setDouble(4, vo.getLatitude()); + ps.setDouble(5,vo.getSog()); + ps.setDouble(6,vo.getCog()); + ps.setInt(7, vo.getHeading()); + ps.setInt(8, vo.getRot()); + ps.setString(9, vo.getZoneId()); + // ps.addBatch(); + ps.execute(); + + } catch (Exception e) { +// logger.error("insertData error", e); + + + } + + } +// ps.executeBatch(); + + con.commit(); + + + } catch (Exception e) { + logger.error("insertData error", e); + } finally { + + if(ps!=null) { + try { + ps.close(); + } catch (SQLException e) { + logger.error("insertData PreparedStatement close error",e); + } + } + if(con!=null) { + try { + con.commit(); + con.setAutoCommit(true); + } catch (SQLException e) { + logger.error("insertData commit error",e); + } + } + } + + }*/ + +// /** +// * Insert colums 성성 +// * @param columnList +// * @return +// */ +// private String getInsertCols(List columnList) { +// StringBuilder result=new StringBuilder(); +// for (int i = 0; i < columnList.size(); i++) { +// result.append(columnList.get(i).getName()); +// //마지막에는 ,를 안붙이기 위해 +// if(i!=columnList.size()-1) +// result.append(","); +// } +// return result.toString(); +// } +// +// +// private String getInsertValueParams(List columnList) { +// StringBuilder result=new StringBuilder(); +// for (int i = 0; i < columnList.size(); i++) { +// result.append(setInsertParam(columnList.get(i))); +// //마지막에는 ,를 안붙이기 위해 +// if(i!=columnList.size()-1) +// result.append(","); +// } +// return result.toString(); +// } +// +// /** +// * 파라미터는 ? 로 표현하여 ps.set~~~으로... +// * @param column +// * @return +// */ +// private String setInsertParam(Column column) { +// switch (dbType) { +// case ORACLE: +// return setInsertParamOracle(column); +// default: +// //mariadb default +// return setInsertParamMariadb(column); +// } +// +// +// } +// +// +// private String setInsertParamMariadb(Column column) { +// +// if(column.isCustom()) { +// return column.getCustomStr(); +// }else { +// switch (column.getColumnTypeName()) { +// case "DATE": +// case "DATETIME": +// return "STR_TO_DATE(?,'%Y%m%d%H%i%S')"; +// case "TIMESTAMP": +// case "TIMESTAMP_WITH_TIMEZONE": +// return "STR_TO_DATE(?,'%Y%m%d%H%i%S%f')"; +// case "TIME": +// case "TIME_WITH_TIMEZONE": +// return "STR_TO_DATE(?,'%H%i%S')"; +// default: +// return "?"; +// } +// } +// } +// +// +// +// +// private String setInsertParamOracle(Column column) { +// +// if(column.isCustom()) { +// return column.getCustomStr(); +// }else { +// switch (column.getColumnTypeName()) { +// case "DATE": +// case "DATETIME": +// return "TO_DATE(?,'yyyymmddhh24miss')"; +// case "TIMESTAMP": +// case "TIMESTAMP_WITH_TIMEZONE": +// return "TO_TIMESTAMP(?,'yyyymmddhh24missff')"; +// case "TIME": +// case "TIME_WITH_TIMEZONE": +// return "TO_DATE(?,'hh24miss')"; +// default: +// return "?"; +// } +// } +// +// } + + + + + +} diff --git a/radar/src/main/java/kr/gmtc/tss/db/DbConfig.java b/radar/src/main/java/kr/gmtc/tss/db/DbConfig.java new file mode 100644 index 0000000..e3afc58 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/db/DbConfig.java @@ -0,0 +1,41 @@ +package kr.gmtc.tss.db; + +import javax.sql.DataSource; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +//@MapperScan(value = "kr.gmtc.eyesvtss.mapper", sqlSessionFactoryRef = "batchSqlSessionFactory" ) +@EnableTransactionManagement +public class DbConfig { + + @Bean(name = "dbDataSource") + @ConfigurationProperties(prefix = "spring.db.datasource") + public DataSource db5DataSource() { + + return DataSourceBuilder.create().build(); + } + + @Bean(name="batchSqlSessionFactory") + public SqlSessionFactory batchSqlSessionFactoryBean(@Qualifier("dbDataSource") DataSource batchDataSource, ApplicationContext applicationContext) + throws Exception { + SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); + factoryBean.setDataSource(batchDataSource); + factoryBean.setConfigLocation(applicationContext.getResource("classpath:/mybatis-config.xml")); + return factoryBean.getObject(); + } +// +// @Bean(name = "packetQ") +// public Queue packetQ(){ +// return new LinkedBlockingQueue(); +// } +} + diff --git a/radar/src/main/java/kr/gmtc/tss/filelog/DataLogger.java b/radar/src/main/java/kr/gmtc/tss/filelog/DataLogger.java new file mode 100644 index 0000000..c25b4eb --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/filelog/DataLogger.java @@ -0,0 +1,85 @@ +package kr.gmtc.tss.filelog; + +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.tss.data.vo.RadarTrackVO; +import kr.gmtc.tss.main.MainServer; +import kr.gmtc.tss.util.FileUtil; + +public class DataLogger implements Runnable { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Queue radarTrackQueue; + private boolean isRunning = true; + private int listChunkSize = 100; + private long sleepMillis; + + public DataLogger(Queue radarTrackQueue, int listChunkSize, long sleepMillis) { + this.radarTrackQueue = radarTrackQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + String [] chunkArr = getChunkMessageArr(radarTrackQueue); + for (int i = 0; i < chunkArr.length; i++) { + FileUtil.writeLogFile(getMessageBody(chunkArr[i]), MainServer.DATA_FILE_NAME); + } + + } catch (Exception e) { + logger.info("-- [SqlLogger] LogSave error : " +e.getLocalizedMessage()); + } + + sleep(sleepMillis); + } + } + + private String [] getChunkMessageArr(Queue radarTrackQueue) { + int loopCnt = 0; + + if(radarTrackQueue.size()>listChunkSize) { + loopCnt = listChunkSize; + }else { + loopCnt = radarTrackQueue.size(); + } + + String [] chunkArr = new String[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i] = radarTrackQueue.poll(); + } + + return chunkArr; + } + + private String getMessageBody(String str) { + StringBuilder sb = new StringBuilder(); + sb.append(str); + sb.append("\n"); + return sb.toString(); + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[SqlLogger] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} \ No newline at end of file diff --git a/radar/src/main/java/kr/gmtc/tss/filelog/MessageBodyLogger.java b/radar/src/main/java/kr/gmtc/tss/filelog/MessageBodyLogger.java new file mode 100644 index 0000000..c9e3534 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/filelog/MessageBodyLogger.java @@ -0,0 +1,110 @@ +package kr.gmtc.tss.filelog; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.tss.data.vo.RadarTrackVO; +import kr.gmtc.tss.main.MainServer; +import kr.gmtc.tss.util.FileUtil; + +public class MessageBodyLogger implements Runnable { + +private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Queue messageBodyQueue; + private boolean isRunning = true; + private int listChunkSize = 100; + private long sleepMillis; + + public MessageBodyLogger(Queue messageBodyQueue, int listChunkSize, long sleepMillis) { + this.messageBodyQueue = messageBodyQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + RadarTrackVO [] chunkArr = getChunkMessageArr(messageBodyQueue); + for (int i = 0; i < chunkArr.length; i++) { + //logger.error(getMessageBody(chunkArr[i])); + FileUtil.writeLogFile(getMessageBody(chunkArr[i]), MainServer.FILE_LOG_NAME); + } + + } catch (Exception e) { + logger.info("-- [SqlLogger] LogSave error : " +e.getLocalizedMessage()); + } + + sleep(sleepMillis); + } + } + + private RadarTrackVO [] getChunkMessageArr(Queue messageBodyQueue) { + int loopCnt = 0; + + if(messageBodyQueue.size()>listChunkSize) { + loopCnt = listChunkSize; + }else { + loopCnt = messageBodyQueue.size(); + } + + RadarTrackVO [] chunkArr = new RadarTrackVO[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i] = messageBodyQueue.poll(); + } + + return chunkArr; + } + +// private String getMessageBody(String str) { +// Date date = new Date(); +// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// +// StringBuilder sb = new StringBuilder(); +// +// sb.append(formatter.format(date)); +// sb.append(" "); +// sb.append(str); +// +// return sb.toString(); +// } + + private String getMessageBody(RadarTrackVO vo) { + ObjectMapper mapper = new ObjectMapper(); + StringBuilder sb = new StringBuilder(); + String str; + try { + str = mapper.writeValueAsString(vo); + + sb.append(str); + sb.append("\n"); + + } catch (JsonProcessingException e) { + logger.debug("[SqlLogger] sleep error : "+e.getLocalizedMessage()); + } + return sb.toString(); + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[SqlLogger] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} diff --git a/radar/src/main/java/kr/gmtc/tss/kafka/KafkaTopicReader.java b/radar/src/main/java/kr/gmtc/tss/kafka/KafkaTopicReader.java new file mode 100644 index 0000000..79a522c --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/kafka/KafkaTopicReader.java @@ -0,0 +1,53 @@ +package kr.gmtc.tss.kafka; + + +import java.time.Duration; +import java.util.Collections; +import java.util.Properties; +import java.util.Queue; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KafkaTopicReader implements Runnable { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private final String bootstrapServers; + private final String topic; + + Queue rcvQueue; + + public KafkaTopicReader(String bootstrapServers, String topic, Queue rcvQueue) { + this.bootstrapServers = bootstrapServers; + this.topic = topic; + this.rcvQueue = rcvQueue; + } + + public void run() { + Properties props = new Properties(); + props.put("bootstrap.servers", bootstrapServers); + props.put("group.id", "kafka-topic-reader"); + props.put("auto.offset.reset", "earliest"); + props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); + props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); + try (KafkaConsumer consumer = new KafkaConsumer<>(props)) { + + // 토픽 구독 + consumer.subscribe(Collections.singletonList(topic)); + + while (true) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + + if (records.count() > 0) logger.info("topic {} 수신 건수 {}", topic, records.count()); + + for (ConsumerRecord record : records) { + rcvQueue.add(record.value()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/radar/src/main/java/kr/gmtc/tss/main/MainServer.java b/radar/src/main/java/kr/gmtc/tss/main/MainServer.java new file mode 100644 index 0000000..0776a2d --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/main/MainServer.java @@ -0,0 +1,500 @@ +package kr.gmtc.tss.main; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.reactive.function.client.WebClient; + +import kr.gmt.so.state.StateManager; +import kr.gmt.so.state.model.SystemState; +import kr.gmtc.tss.data.DataInsertRunnable; +import kr.gmtc.tss.data.ParseTargetRunnable; +import kr.gmtc.tss.data.TargetManageRunnable; +import kr.gmtc.tss.data.vo.RadarTrackVO; +import kr.gmtc.tss.db.BatchInsertManager; +import kr.gmtc.tss.filelog.DataLogger; +import kr.gmtc.tss.filelog.MessageBodyLogger; +import kr.gmtc.tss.kafka.KafkaTopicReader; +import kr.gmtc.tss.netty.StringClient; +import kr.gmtc.tss.sqllog.SqlLogger; +import kr.gmtc.tss.util.ArrayBlockingLoggingQueue; +import kr.gmtc.tss.util.FileUtil; + +@EnableScheduling +@Component +public class MainServer implements InitializingBean { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Value("${kafka.bootstrapServers}") + private String bootstrapServers; + + @Value("${kafka.topic}") + private String topic; + + @Value("${file-zip-path}") + private String fileZipPath; + + @Value("${file-zip-bak-path}") + private String fileZipBakPath; + + @Value("${file-make-time}") + private int fileMakeTime; + + @Value("${data-zip-path}") + private String dataZipPath; + + @Value("${data-zip-bak-path}") + private String dataZipBakPath; + + @Value("${data-make-time}") + private int dataMakeTime; + + @Value("${flag.database}") + private boolean flagDataBase; + + @Value("${flag.datafile}") + private boolean flagDataFile; + + @Value("${flag.file}") + private boolean flagFile; + + @Value("${client.server.ip:127.0.0.1}") + private String tcpServerIp="127.0.0.1"; + + @Value("${client.server.port:8030}") + private int tcpServerPort=8030; + + + @Value("${client.reconn-time-sec:3000}") + private long reconnTime=3000; + + @Value("${client.queue-count:10000}") + private int queueCount=100000; + + @Value("${dynamic-dedupl.set-size:10000}") + private int dynamicSetSize; + + @Value("${dynamic-dedupl.set-remove-unit-size:500}") + private int dynamicRemoveUnitSize; + + @Value("${spring.db.batch-insert-size:1000}") + private int batchInsertSize; + + @Value("${process.queue-chunk-size:1000}") + private int queueChunkSize; + + @Autowired + @Qualifier("batchSqlSessionFactory") + public SqlSessionFactory sqlSessionFactory; + private SqlSession session; + + public static String FILE_LOG_NAME; + public static String DATA_FILE_NAME; + + + @Value("${selep-time-ms.parse-target:50}") + private long parseTargetSleepMs; + + @Value("${selep-time-ms.target-manage:50}") + private long targetManageSleepMs; + + @Value("${selep-time-ms.data-insert:50}") + private long dataInsertSleepMs; + + @Value("${selep-time-ms.sql-logger:50}") + private long sqlLoggerSleepMs; + + @Value("${classification}") + private String classification; + + @Value("${swclassification}") + private String swclassification; + + @Value("${logclassification}") + private String logclassification; + + StringClient client; + KafkaTopicReader kafkaTopicReader; + ParseTargetRunnable parserRunnable; + DataLogger dataLoggerRunnable; + TargetManageRunnable targetManageRunnable; + SqlLogger sqlLoggerRunnable; + BatchInsertManager batchInsertManager; + DataInsertRunnable dataInsertRunnable; + MessageBodyLogger messageBodyLogger; + + List threadList = new ArrayList(); + + Queue rcvQueue; + Queue radarQueue; + + Queue sqlLogRadarQueue; + Queue dataFileQueue; + Queue sqlLogRadarLastQueue; + + Queue messageBodyQueue; + + @Value("${rest.server.ip}") + private String restServerIp; + + @Value("${rest.server.port}") + private String restServerPort; + + @Value("${rest.server.path}") + private String restServerPath; + + @Bean(name = "rcvQueue") + public Queue getRcvQueue() { + return rcvQueue; + } + + @Bean(name = "radarQueue") + public Queue getRadarQueue() { + return radarQueue; + } + + @Bean(name = "dataFileQueue") + public Queue getDataFileQueue() { + return dataFileQueue; + } + + @Bean(name = "sqlLogRadarQueue") + public Queue getSqlLogRadarQueue() { + return sqlLogRadarQueue; + } + + @Bean(name = "sqlLogRadarLastQueue") + public Queue getSqlLogRadarLastQueue() { + return sqlLogRadarLastQueue; + } + + @Bean(name = "messageBodyQueue") + public Queue getMessageBodyQueue() { + return messageBodyQueue; + } + + @Autowired + private FileUtil fileUtil; + + @Autowired + private StateManager stateMgr; + // private boolean swBeforeStatus = true; + + public static int LAST_DATA_CNT = 0; + + WebClient webClient = WebClient.builder() + .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) + .build(); + + @PostConstruct + public void init() { + logger.info("DataQueue Count : "+queueCount); + + stateMgr.updateState(); + + rcvQueue=new ArrayBlockingLoggingQueue<>(queueCount); + sqlLogRadarQueue=new ArrayBlockingLoggingQueue<>(queueCount); + sqlLogRadarLastQueue=new ArrayBlockingLoggingQueue<>(queueCount); + radarQueue=new ArrayBlockingLoggingQueue<>(queueCount); + dataFileQueue=new ArrayBlockingLoggingQueue<>(queueCount); + messageBodyQueue=new ArrayBlockingLoggingQueue<>(queueCount); + + // LAST TABLE 데이터 확인 + // 20230809 cjj last 사용하지 않도록 + //DBLastDataStatus(); + + // 최초 한번만 실행 - 로그파일이 없을 시 생성 + if (flagFile) FILE_LOG_NAME = fileUtil.createLogFile(fileZipPath, fileZipBakPath, fileMakeTime); // rest log file + if (flagDataFile) DATA_FILE_NAME = fileUtil.createLogFile(dataZipPath, dataZipBakPath, dataMakeTime); // logstash data file log + } + + @PreDestroy + public void destroy() { +// parserRunnable; +// targetManageRunnable; +// sqlLoggerRunnable; +// batchInsertManager; +// dataInsertRunnable.s; +// client.isInterrupted(); + logger.info("Pre destroy called!!"); + client.interrupt(); + dataInsertRunnable.setRunning(false); + sqlLoggerRunnable.setRunning(false); + parserRunnable.setRunning(false); + //targetManageRunnable.setRunning(false); +// sqlSessionFactory.ge +// batchInsertManager.setRunning(false); + +// for (int i = 0; i < threadList.size(); i++) { +// try { +// +// logger.info("["+threadList.get(i).getClass().getName() +"/"+threadList.get(i).getName()+"] thread destroy"); +// threadList.get(i).interrupt(); +// } catch (Exception e) { +// logger.error("Thread interrupt error - ",e); +// +// } +// +// } + } + + + @Override + public void afterPropertiesSet() throws Exception { + if(flagDataBase) startDataInsertThread(); + if(flagDataFile) startDataLoggerThread(); + if(flagFile) startMessageBodyThread(); + + startKafkaThread(); + startParserThread(); + startSqlLoggerThread(); + // REST API로 변경 + // startNettyClient(); + } + + private void getClient(String ip, String port, String path, MultiValueMap param){ + String result = webClient + .mutate() + .baseUrl("http://" + ip + ":" + port) + .build() + .get() + .uri(uriBuilder -> uriBuilder.path(path) + .queryParams(param) + .build()) + .retrieve() + .bodyToMono(String.class) + .block(); + + rcvQueue.add(result); + } + +// @Scheduled(cron = "${process.rest-cron}") + public void restRecv() { + checkQueueSize(); + + MultiValueMap param = new LinkedMultiValueMap(); + getClient(restServerIp, restServerPort, restServerPath, param); + } + + @Scheduled(cron = "${process.status-check-cron}") + private void chkThreadStatus() throws InterruptedException{ + + stateMgr.updateState(); + + boolean running = true; + boolean swNewStatus = stateMgr.isActive(); + + // // 이중화 Active / Standby 상태 변경 체크 + // if(swBeforeStatus != swNewStatus){ + + // parserRunnable.setRunning(swNewStatus); + // dataInsertRunnable2.setRunning(swNewStatus); + // dataLoggerRunnable.setRunning(swNewStatus); + // sqlLoggerRunnable.setRunning(swNewStatus); + // messageBodyLogger.setRunning(swNewStatus); + + // } + + // 해당 프로그램이 Active일때 Thread Interrupt 유무 체크 + if(swNewStatus){ + + for(Thread ct : threadList ){ + if(ct.isInterrupted()){ + running = false; + break; + } + } + + if(running){ + stateMgr.updateState(SystemState.Normal); + }else{ + stateMgr.updateState(SystemState.Error); + } + } + + // swBeforeStatus = stateMgr.isActive(); + + // logger.info("swBeforeStatus : " + swBeforeStatus); + } + + @Scheduled(cron = "${process.file-backup-cron}") + public void fileRecv() throws Exception{ + if (flagFile) { + /* 파일 압축 */ + fileUtil.createZipFile(fileZipPath, fileZipBakPath, fileMakeTime); + } + } + + @Scheduled(cron = "${process.data-backup-cron}") + public void dataFileRecv() throws Exception{ + if (flagDataFile) { + /* 파일 압축 */ + fileUtil.createZipFile(dataZipPath, dataZipBakPath, dataMakeTime); + } + } + + // 매 시간 10분 간격 으로 실행 + @Scheduled(cron = "${process.file-make-cron}") + public void fileMake() throws Exception{ + if (flagFile) { + FILE_LOG_NAME = fileUtil.createLogFile(fileZipPath, fileZipBakPath, fileMakeTime); + } + } + + @Scheduled(cron = "${process.data-make-cron}") + public void dataFileMake() throws Exception{ + if (flagDataFile) { + DATA_FILE_NAME = fileUtil.createLogFile(dataZipPath, dataZipBakPath, dataMakeTime); + } + } + + private void checkQueueSize() { + if(rcvQueue.size()==queueCount) { + logger.error("rcvQueue is Full!!"); + } + if(radarQueue.size()==queueCount) { + logger.error("radarQueue is Full!!"); + } + if(sqlLogRadarQueue.size()==queueCount) { + logger.error("sqlLogRadarQueue is Full!!"); + } + if(sqlLogRadarLastQueue.size()==queueCount) { + logger.error("sqlLogRadarLastQueue is Full!!"); + } + if(messageBodyQueue.size()==queueCount) { + logger.error("messageBodyQueue is Full!!"); + } + } + + public void startNettyClient() { + //StringClient client = new StringClient("127.0.0.1", tcpServerPort, rcvQueue, reconnTime); + //this.client=client; + //client.start(); + + //threadList.add(client); + } + + public void startKafkaThread() { + KafkaTopicReader topicReader = new KafkaTopicReader(bootstrapServers, topic, rcvQueue); + this.kafkaTopicReader=topicReader; + + Thread thread = new Thread(topicReader); + thread.start(); + + threadList.add(thread); + } + + public void startParserThread() { + ParseTargetRunnable parserRunnable = new ParseTargetRunnable(rcvQueue, radarQueue, dataFileQueue, messageBodyQueue, queueChunkSize, parseTargetSleepMs, flagFile, flagDataBase, flagDataFile, classification, swclassification, logclassification); + this.parserRunnable=parserRunnable; + Thread thread = new Thread(parserRunnable); + thread.start(); + threadList.add(thread); + parserRunnable.getCountAndSetZero(); + } + + public void startDataInsertThread() { + BatchInsertManager batchInsertManager = new BatchInsertManager(sqlSessionFactory, sqlLogRadarQueue, sqlLogRadarLastQueue); + this.batchInsertManager=batchInsertManager; + + DataInsertRunnable dataInsertRunnable = new DataInsertRunnable(radarQueue, batchInsertManager, dataInsertSleepMs); + this.dataInsertRunnable=dataInsertRunnable; + + Thread thread = new Thread(dataInsertRunnable); + thread.start(); + + threadList.add(thread); + } + + public void startDataLoggerThread() { + DataLogger dataLoggerRunnable = new DataLogger(dataFileQueue, queueChunkSize, sqlLoggerSleepMs); + this.dataLoggerRunnable = dataLoggerRunnable; + + Thread thread = new Thread(dataLoggerRunnable); + thread.start(); + + threadList.add(thread); + } + + public void startSqlLoggerThread() { + SqlLogger sqlLoggerRunnable = new SqlLogger(sqlLogRadarQueue, sqlLogRadarLastQueue, queueChunkSize, sqlLoggerSleepMs); + this.sqlLoggerRunnable = sqlLoggerRunnable; + + Thread thread = new Thread(sqlLoggerRunnable); + thread.start(); + + threadList.add(thread); + } + + public void startMessageBodyThread() { + MessageBodyLogger messageBodyLogger = new MessageBodyLogger(messageBodyQueue, queueChunkSize, sqlLoggerSleepMs); + this.messageBodyLogger = messageBodyLogger; + + Thread thread = new Thread(messageBodyLogger); + thread.start(); + + threadList.add(thread); + } + + public void DBLastDataStatus() { + openSession(false); + + String sql = "SELECT COUNT(*) FROM SACP_RADAR_TRACK_LAST "; + + PreparedStatement ps = null; + Connection con = null; + + con = session.getConnection(); + + try { + if(con.isClosed() || !con.isValid(1)) { + closeSession(); + openSession(true); + con = session.getConnection(); + } + con.setAutoCommit(false); + ps = con.prepareStatement(sql); + ResultSet rs = ps.executeQuery(); + + while (rs.next()) { + LAST_DATA_CNT = rs.getInt(1); + } + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public void openSession(boolean forceOpen) { + if(session==null||forceOpen) + session = sqlSessionFactory.openSession(); + } + + public void closeSession() { + if(session!=null) + session.close(); + } +} \ No newline at end of file diff --git a/asde/src/main/java/kr/gmtc/tss/netty/StringClient.java b/radar/src/main/java/kr/gmtc/tss/netty/StringClient.java similarity index 100% rename from asde/src/main/java/kr/gmtc/tss/netty/StringClient.java rename to radar/src/main/java/kr/gmtc/tss/netty/StringClient.java diff --git a/asde/src/main/java/kr/gmtc/tss/netty/StringClientHandler.java b/radar/src/main/java/kr/gmtc/tss/netty/StringClientHandler.java similarity index 100% rename from asde/src/main/java/kr/gmtc/tss/netty/StringClientHandler.java rename to radar/src/main/java/kr/gmtc/tss/netty/StringClientHandler.java diff --git a/radar/src/main/java/kr/gmtc/tss/sqllog/SqlLogger.java b/radar/src/main/java/kr/gmtc/tss/sqllog/SqlLogger.java new file mode 100644 index 0000000..75f3c0c --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/sqllog/SqlLogger.java @@ -0,0 +1,135 @@ +package kr.gmtc.tss.sqllog; + +import java.text.SimpleDateFormat; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.tss.data.vo.RadarTrackVO; +import kr.gmtc.tss.main.MainServer; + +public class SqlLogger implements Runnable { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private Queue sqlLogRadarTrackQueue; + private Queue sqlLogRadarTrackLastQueue; + private boolean isRunning=true; + private int listChunkSize= 100; + private long sleepMillis; + + public SqlLogger(Queue sqlLogRadarTrackQueue, Queue sqlLogRadarTrackLastQueue, int listChunkSize, long sleepMillis) { + this.sqlLogRadarTrackQueue = sqlLogRadarTrackQueue; + this.sqlLogRadarTrackLastQueue = sqlLogRadarTrackLastQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + RadarTrackVO [] chunkArr = getChunkTrackArr(sqlLogRadarTrackQueue); + for (int i = 0; i < chunkArr.length; i++) { + logger.error(getInsertTrackSql(chunkArr[i])); + } + +// chunkArr = getChunkTrackArr(sqlLogRadarTrackLastQueue); +// +// for (int i = 0; i < chunkArr.length; i++) { +// logger.error(getInsertLastTrackSql(chunkArr[i])); +// } + + } catch (Exception e) { + logger.info("-- [SqlLogger] LogSave error : " +e.getLocalizedMessage()); + } + + sleep(sleepMillis); + } + } + + private RadarTrackVO [] getChunkTrackArr(Queue sqlQueue) { + int loopCnt=0; + + if(sqlQueue.size()>listChunkSize) { + loopCnt=listChunkSize; + }else { + loopCnt=sqlQueue.size(); + } + + RadarTrackVO [] chunkArr = new RadarTrackVO[loopCnt]; + for (int i = 0; i < loopCnt; i++) { + chunkArr[i]=sqlQueue.poll(); + } + return chunkArr; + } + + private String getInsertTrackSql(RadarTrackVO vo) { + SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd"); + String now_dt = format.format(vo.getRecptnDt()); + //String tableName = "SACP_RADAR_TRACK_" + now_dt; + String tableName = "SACP_RADAR_TRACK"; + + StringBuilder sb = new StringBuilder(); + + sb.append("INSERT INTO "); + sb.append(tableName); + sb.append(" (TRGT_ID, RECPTN_DT, LAT, LON, SPD, COS, DETCT_CNT, UNDETCT_CNT, REGISTER_ID)"); + sb.append(" VALUES ("); + sb.append("'"); sb.append(vo.getTrgtId()); sb.append("',"); + sb.append("'"); sb.append(vo.getRecptnDt()); sb.append("',"); + sb.append(vo.getLat()); sb.append(","); + sb.append(vo.getLon()); sb.append(","); + sb.append(vo.getSpd()); sb.append(","); + sb.append(vo.getCos()); sb.append(","); + sb.append(vo.getDetctCnt()); sb.append(","); + sb.append(vo.getUndetctCnt()); sb.append(","); + sb.append("'SYSTEM')"); + + return sb.toString(); + } + + private String getInsertLastTrackSql(RadarTrackVO vo) { + StringBuilder sb = new StringBuilder(); + if(MainServer.LAST_DATA_CNT > 0) { + // update + sb.append("UPDATE SACP_RADAR_TRACK_LAST"); + sb.append(" SET RECPTN_DT = "); sb.append("'");sb.append(vo.getRecptnDt());sb.append("'"); + sb.append(" , LAT = "); sb.append(vo.getLat()); + sb.append(" , LON = "); sb.append(vo.getLon()); + sb.append(" , SPD = "); sb.append(vo.getSpd()); + sb.append(" , COS = "); sb.append(vo.getCos()); + sb.append(" , UPDUSR_ID = "); sb.append("'");sb.append(vo.getRegisterId());sb.append("'"); + sb.append(" , UPDT_DT = TO_TIMESTAMP(SYSDATE,'yyyyMMdd')"); + sb.append(" WHERE TRGT_ID = "); sb.append("'");sb.append(vo.getTrgtId());sb.append("')"); + } else { + // insert + sb.append(" INSERT INTO SACP_RADAR_TRACK_LAST"); + sb.append(" (TRGT_ID, RECPTN_DT, LAT, LON, SPD, COS, REGISTER_ID)"); + sb.append(" VALUES ("); + sb.append("'"); sb.append(vo.getTrgtId()); sb.append("',"); + sb.append("'"); sb.append(vo.getRecptnDt()); sb.append("',"); + sb.append(vo.getLat()); sb.append(","); + sb.append(vo.getLon()); sb.append(","); + sb.append(vo.getSpd()); sb.append(","); + sb.append(vo.getCos()); sb.append(","); + sb.append("'"); sb.append(vo.getRegisterId()); sb.append("')"); + } + + return sb.toString(); + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[SqlLogger] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} diff --git a/radar/src/main/java/kr/gmtc/tss/status/ContextDestroyEventListener.java b/radar/src/main/java/kr/gmtc/tss/status/ContextDestroyEventListener.java new file mode 100644 index 0000000..44c5242 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/status/ContextDestroyEventListener.java @@ -0,0 +1,8 @@ +package kr.gmtc.tss.status; + +public interface ContextDestroyEventListener { + /** + * Context destroy event handler. + */ + void onDestroy(); +} diff --git a/radar/src/main/java/kr/gmtc/tss/status/ContextDestroyStatus.java b/radar/src/main/java/kr/gmtc/tss/status/ContextDestroyStatus.java new file mode 100644 index 0000000..93b76dc --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/status/ContextDestroyStatus.java @@ -0,0 +1,64 @@ +package kr.gmtc.tss.status; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; +import java.util.ArrayList; +import java.util.List; + +@Component +@Scope("singleton") +public class ContextDestroyStatus { + /** + * Logger. + */ + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * linstener list. + */ + private final List contextDestroyEventListeners = new ArrayList(); + + /** + * context destroy 여부 상태 값. + */ + private boolean shutdown = false; + + /** + * Shutdown flag 설정 등. 등록된 listener의 onDestroy event를 fire 한다. + */ + @PreDestroy + public void destroy() { + logger.info("Called destroy()!"); + shutdown = true; + + for (ContextDestroyEventListener listener : contextDestroyEventListeners) { + listener.onDestroy(); + } + } + + /** + * @return destroy 된다면 true. 동작 중에는 false. + */ + public boolean getShutdownStat() { + return shutdown; + } + public void setShutdownStat(boolean shutdown ) { + this.shutdown=shutdown; +// return shutdown; + } + + + /** + * @param listener + * event fire 대상 class. + */ + public void addListener(final ContextDestroyEventListener listener) { + contextDestroyEventListeners.add(listener); + logger.info("addListener ({}) complete. Listeners count is {}.", listener.getClass().getName(), + contextDestroyEventListeners.size()); + } +} diff --git a/radar/src/main/java/kr/gmtc/tss/status/CountStatus.java b/radar/src/main/java/kr/gmtc/tss/status/CountStatus.java new file mode 100644 index 0000000..8267b72 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/status/CountStatus.java @@ -0,0 +1,240 @@ +package kr.gmtc.tss.status; + +public class CountStatus { + + private int rcvPos=0; + private int rcvStat=0; + private int savePos=0; + private int saveLast=0; + private int saveStatic=0; + private int failPos=0; + private int failLast=0; + private int failStatic=0; + private int exceptPos=0; + + + private int rcvQueueSize=0; + private int dynamicVoQueueSize=0; + private int staticVoQueueSize=0; + private int dynamicInsertQueueSize=0; + private int sqlLogDynamicQueueSize=0; + private int sqlLogDynamicLastQueueSize=0; + private int sqlLogStaticQueueSize=0; + + + + public CountStatus(int rcvPos, int rcvStat) { + this.rcvPos=rcvPos; + this.rcvStat=rcvStat; + } + + public CountStatus(int savePos, int saveLast, int saveStatic, int failPos, int failLast, int failStatic) { + this.savePos=savePos; + this.saveLast=saveLast; + this.saveStatic=saveStatic; + this.failPos=failPos; + this.failLast=failLast; + this.failStatic=failStatic; + } + + public CountStatus() { + + } + + public int getRcvPos() { + return rcvPos; + } + + public void setRcvPos(int rcvPos) { + this.rcvPos = rcvPos; + } + + public int getRcvStat() { + return rcvStat; + } + + public void setRcvStat(int rcvStat) { + this.rcvStat = rcvStat; + } + + public int getSavePos() { + return savePos; + } + + public void setSavePos(int savePos) { + this.savePos = savePos; + } + + public int getSaveLast() { + return saveLast; + } + + public void setSaveLast(int saveLast) { + this.saveLast = saveLast; + } + + public int getSaveStatic() { + return saveStatic; + } + + public void setSaveStatic(int saveStatic) { + this.saveStatic = saveStatic; + } + + public int getFailPos() { + return failPos; + } + + public void setFailPos(int failPos) { + this.failPos = failPos; + } + + public int getFailLast() { + return failLast; + } + + public void setFailLast(int failLast) { + this.failLast = failLast; + } + + public int getFailStatic() { + return failStatic; + } + + public void setFailStatic(int failStatic) { + this.failStatic = failStatic; + } + + public int getExceptPos() { + return exceptPos; + } + + public void setExceptPos(int exceptPos) { + this.exceptPos = exceptPos; + } + + + public int getRcvQueueSize() { + return rcvQueueSize; + } + + public void setRcvQueueSize(int rcvQueueSize) { + this.rcvQueueSize = rcvQueueSize; + } + + public int getDynamicVoQueueSize() { + return dynamicVoQueueSize; + } + + public void setDynamicVoQueueSize(int dynamicVoQueueSize) { + this.dynamicVoQueueSize = dynamicVoQueueSize; + } + + public int getStaticVoQueueSize() { + return staticVoQueueSize; + } + + public void setStaticVoQueueSize(int staticVoQueueSize) { + this.staticVoQueueSize = staticVoQueueSize; + } + + public int getDynamicInsertQueueSize() { + return dynamicInsertQueueSize; + } + + public void setDynamicInsertQueueSize(int dynamicInsertQueueSize) { + this.dynamicInsertQueueSize = dynamicInsertQueueSize; + } + + public int getSqlLogDynamicQueueSize() { + return sqlLogDynamicQueueSize; + } + + public void setSqlLogDynamicQueueSize(int sqlLogDynamicQueueSize) { + this.sqlLogDynamicQueueSize = sqlLogDynamicQueueSize; + } + + public int getSqlLogDynamicLastQueueSize() { + return sqlLogDynamicLastQueueSize; + } + + public void setSqlLogDynamicLastQueueSize(int sqlLogDynamicLastQueueSize) { + this.sqlLogDynamicLastQueueSize = sqlLogDynamicLastQueueSize; + } + + public int getSqlLogStaticQueueSize() { + return sqlLogStaticQueueSize; + } + + public void setSqlLogStaticQueueSize(int sqlLogStaticQueueSize) { + this.sqlLogStaticQueueSize = sqlLogStaticQueueSize; + } + + public void initZero() { + + rcvPos = 0; + rcvStat = 0; + savePos = 0; + saveLast = 0; + saveStatic = 0; + failPos = 0; + failLast = 0; + failStatic = 0; + + } + + public String getCountLog() { + StringBuilder sb = new StringBuilder(); + + sb.append( "\r\n"); + sb.append( "===============================================\r\n" ); + sb.append( " Count Info \r\n" ); + sb.append( "===============================================\r\n" ); + sb.append( " 위치정보 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 수신 / 저장성공 / 저장실패 / 제외 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", rcvPos)+" / "+String.format(" %5s", savePos)+" / "+String.format(" %5s", failPos)+" / "+String.format(" %5s", exceptPos)+"\r\n" ); + sb.append( "===============================================\r\n" ); + sb.append( " 정적정보 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 수신 / 저장성공 / 저장실패 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", rcvStat)+" / "+String.format(" %5s", saveStatic)+" / "+String.format(" %5s", failStatic)+" / \r\n"); + sb.append( "===============================================\r\n");; + sb.append( " 최종위치정보 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 저장성공 / 저장실패 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", saveLast)+" / "+String.format(" %5s", failLast)+" / \r\n"); + sb.append( "===============================================\r\n"); + sb.append( " 큐 상태 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 수신 / 동적 / 동적(입력) / 정적 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", rcvQueueSize)+" / "+String.format(" %5s", dynamicVoQueueSize)+" / "+String.format(" %5s", dynamicInsertQueueSize)+" / "+String.format(" %5s", staticVoQueueSize)+" / \r\n"); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " SQL \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 동적 / 최종 / 정적 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", sqlLogDynamicQueueSize)+" / "+String.format(" %5s", sqlLogDynamicLastQueueSize)+" / "+String.format(" %5s", sqlLogStaticQueueSize)+" / \r\n"); + sb.append( "===============================================\r\n"); + +// + +// private int rcvQueueSize=0; +// private int dynamicVoQueueSize=0; +// private int staticVoQueueSize=0; +// private int dynamicInsertQueueSize=0; +// private int sqlLogDynamicQueueSize=0; +// private int sqlLogDynamicLastQueueSize=0; +// private int sqlLogStaticQueueSize=0; + + + initZero(); + + return sb.toString(); + } + +} diff --git a/radar/src/main/java/kr/gmtc/tss/status/CountingComponent.java b/radar/src/main/java/kr/gmtc/tss/status/CountingComponent.java new file mode 100644 index 0000000..715bfab --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/status/CountingComponent.java @@ -0,0 +1,86 @@ +package kr.gmtc.tss.status; + +import org.springframework.stereotype.Component; + +@Component +public class CountingComponent { + + private int rcvPos=0; + private int rcvStatic=0; + private int savePos=0; + private int failPos=0; + private int saveStatic=0; + private int failStatic=0; + + public int getRcvPos() { + return rcvPos; + } + public void setRcvPos(int rcvPos) { + this.rcvPos = rcvPos; + } + public int getRcvStatic() { + return rcvStatic; + } + public void setRcvStatic(int rcvStatic) { + this.rcvStatic = rcvStatic; + } + public int getSavePos() { + return savePos; + } + public void setSavePos(int savePos) { + this.savePos = savePos; + } + public int getFailPos() { + return failPos; + } + public void setFailPos(int failPos) { + this.failPos = failPos; + } + public int getSaveStatic() { + return saveStatic; + } + public void setSaveStatic(int saveStatic) { + this.saveStatic = saveStatic; + } + public int getFailStatic() { + return failStatic; + } + public void setFailStatic(int failStatic) { + this.failStatic = failStatic; + } + + + + public void initZero() { + rcvPos=0; + rcvStatic=0; + savePos=0; + failPos=0; + saveStatic=0; + failStatic=0; + } + + public String getCountLog() { + String log = "\r\n" + + "===============================================\r\n" + + " Count Info \r\n" + + "===============================================\r\n" + + " 위치정보 \r\n" + + "-----------------------------------------------\r\n" + + " 수신 / 저장성공 / 저장실패 \r\n" + + "-----------------------------------------------\r\n" + + " "+String.format(" %5s", rcvPos)+" / "+String.format(" %5s", savePos)+" / "+String.format(" %5s", failPos)+"\r\n" + + "===============================================\r\n" + + " 정적정보 \r\n" + + "-----------------------------------------------\r\n" + + " 수신 / 저장성공 / 저장실패 \r\n" + + "-----------------------------------------------\r\n" + + " "+String.format(" %5s", rcvStatic)+" / "+String.format(" %5s", saveStatic)+" / "+String.format(" %5s", failStatic)+"\r\n" + + "===============================================\r\n"; + + initZero(); + + return log; + } + +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/ArrayBlockingLoggingQueue.java b/radar/src/main/java/kr/gmtc/tss/util/ArrayBlockingLoggingQueue.java new file mode 100644 index 0000000..ec4f2de --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/ArrayBlockingLoggingQueue.java @@ -0,0 +1,53 @@ +package kr.gmtc.tss.util; + +import java.util.Collection; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class ArrayBlockingLoggingQueue extends ArrayBlockingQueue { + + private static Logger logger = LoggerFactory.getLogger(ArrayBlockingLoggingQueue.class); + + public ArrayBlockingLoggingQueue(int capacity, boolean fair, + Collection c) { + super(capacity, fair, c); + // TODO Auto-generated constructor stub + } + + public ArrayBlockingLoggingQueue(int capacity, boolean fair) { + super(capacity, fair); + // TODO Auto-generated constructor stub + } + + public ArrayBlockingLoggingQueue(int capacity) { + super(capacity); + // TODO Auto-generated constructor stub + } + + @Override + public synchronized boolean add(Object e) { + // TODO Auto-generated method stub + logger.debug(e+""); + return super.add(e); + } + + @Override + public synchronized boolean offer(Object e) { + // TODO Auto-generated method stub + logger.debug(e+""); + return super.offer(e); + } + + @Override + public synchronized boolean offer(Object e, long timeout, TimeUnit unit) throws InterruptedException { + // TODO Auto-generated method stub + logger.debug(e+""); + return super.offer(e, timeout, unit); + } + + +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/FileUtil.java b/radar/src/main/java/kr/gmtc/tss/util/FileUtil.java new file mode 100644 index 0000000..83d9db1 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/FileUtil.java @@ -0,0 +1,224 @@ +package kr.gmtc.tss.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.springframework.stereotype.Component; + +@Component +public class FileUtil { + +// @Value("${file-zip-path}") +// private String fileZipPath; +// +// @Value("${file-zip-bak-path}") +// private String fileZipBakPath; +// +// @Value("${file-make-time}") +// private int fileMakeTime; + +// public static String FILE_LOG_NAME; + + /** + * 로그파일을 압축한다. + * 라이브 데이터 압축을 피하기 위해 20분전 데이터를 압축하는 것으로 세팅 + */ + public void createZipFile(String fileZipPath, String fileZipBakPath, int fileMakeTime) { + + // 압축파일이 저장될 폴더가 존재하는지 확인 + File backDir = new File(fileZipBakPath); + if(!backDir.exists()) { + backDir.mkdirs(); + } + + SimpleDateFormat fileFormatter = new SimpleDateFormat("yyyyMMddHHmm"); + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MINUTE, -20); // 20분전 데이터 확인 + + String time20 = fileFormatter.format(cal.getTime()); + + // 압축할 파일 명 확인. + String bakFileName = "file."+time20+".log"; + + String fileName = ""; + ZipOutputStream zip_out = null; + + // 압축 파일 명 세팅 + StringBuilder sb = new StringBuilder(); + sb.append(bakFileName); + sb.append(".zip"); + fileName = sb.toString(); + + String _path = fileZipPath+"/"+bakFileName; + + File bakFile = new File(_path); + + // 파일이 존재할 경우에만 실행. + if(bakFile.exists()) { + if (fileZipPath.charAt(fileZipPath.length() - 1) != '/') { + _path = _path + "/"; + } + + try { + zip_out = new ZipOutputStream(new FileOutputStream(fileZipBakPath+"/"+fileName)); + zipFolder("", bakFile, zip_out); + zip_out.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + + } catch (IOException e) { + e.printStackTrace(); + + } finally { + + } + } else { + System.out.println("파일이 존재하지 않습니다."); + } + } + + /** + * ZipOutputStream를 넘겨 받아서 하나의 압축파일로 만든다. + * @param parent 상위폴더명 + * @param file 압축할 파일 + * @param zout 압축전체스트림 + * @throws IOException + */ + private void zipFolder(String parent, File file, ZipOutputStream zout) throws IOException { + byte[] data = new byte[2048]; + + int read; + + BufferedInputStream instream = new BufferedInputStream(new FileInputStream(file)); + + ZipEntry zipEntry = new ZipEntry(parent + file.getName()); + zout.putNextEntry(zipEntry); + + while ((read = instream.read(data, 0, 2048)) != -1) { + zout.write(data, 0, read); + } + + zout.flush(); + zout.closeEntry(); + instream.close(); + + file.delete(); // 파일 삭제 + + } + + private void bakFileDelete(String fileZipPath, String date) throws IOException { + File folder = new File(fileZipPath+"/"+date); // file 생성 + + try { + while(folder.exists()){ + File[] files = folder.listFiles(); + + for(File file : files){ + file.delete(); // 하위 파일 삭제 + } + + // 폴더 삭제 + if(files.length == 0 && folder.isDirectory()){ // 하위 파일이 없는지와 폴더인지 확인 후 폴더 삭제 + folder.delete(); // 대상폴더 삭제 + } + } + + } catch(Exception e) { + e.printStackTrace(); + } + } + + /** + * 로그파일을 생성하는 함수 + */ + public String createLogFile(String fileZipPath, String fileZipBakPath, int fileMakeTime) { + File fileDir = new File(fileZipPath); + if(!fileDir.exists()) { + fileDir.mkdirs(); + } + // 현재 시각 중에 분을 구해온다. (minute) + SimpleDateFormat formatter = new SimpleDateFormat("mm"); + String _path = ""; + + Date now = new Date(); + String nowTime = formatter.format(now); + int time = Integer.parseInt(nowTime); + String nowT = ""; + + // 현재 분이 설정한 값의 배수인지 확인한다. + if(time%fileMakeTime == 0){ + if(time == 0) { + nowT = "00"; + }else{ + nowT = String.valueOf(time); + } + }else{ + if(time < fileMakeTime) { + nowT = "00"; + }else{ + nowT = nowTime.substring(0, 1)+"0"; + } + } + + // 생성할 파일명을 설정한다. + SimpleDateFormat fileFormatter = new SimpleDateFormat("yyyyMMddHH"); + String fileTime = fileFormatter.format(now) + nowT; + + try { + _path = fileZipPath+"/file."+fileTime+".log"; + + // static 변수에 값을 세팅한다. + //FILE_LOG_NAME = _path; + + File file = new File(_path); + File parentDir = file.getParentFile(); + if (!parentDir.exists()) { + parentDir.mkdirs(); + } + + if (file.createNewFile()) { + System.out.println("파일 생성 완료"); + } else { + System.out.println("파일 이미 존재"); + } + } catch (IOException e) { + e.printStackTrace(); + } + return _path; + } + + /** + * 파일에 메세지를 쓰는 함수 + * @param msg + * @throws Exception + */ + public static void writeLogFile(String msg, String fileName) throws Exception{ + // File file = new File(FILE_LOG_NAME); + File file = new File(fileName); + + // 파일이 존재할 경우에만 실행 + if(file.exists()) { + FileWriter fw; + try { + fw = new FileWriter(file, true); + fw.write(msg); + fw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + }else { + System.out.println("파일 없음 파일명 확인 필요."); + } + } +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/MapUtil.java b/radar/src/main/java/kr/gmtc/tss/util/MapUtil.java new file mode 100644 index 0000000..5a174cd --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/MapUtil.java @@ -0,0 +1,30 @@ +package kr.gmtc.tss.util; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +public class MapUtil { + + public static ArrayList toKeyArray(Map mapData){ + Set key = mapData.keySet(); + ArrayList keyArr=new ArrayList(); + for (Iterator iterator = key.iterator(); iterator.hasNext();) { + keyArr.add((String)iterator.next()); + } + return keyArr; + } + + + public static ArrayList toArray(Map mapData){ + Set key = mapData.keySet(); + ArrayList dataArr=new ArrayList(); + for (Iterator iterator = key.iterator(); iterator.hasNext();) { +// dataArr.add((String)iterator.next()); + dataArr.add(mapData.get(iterator.next())); + } + return dataArr; + } + +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/WebClientConfig.java b/radar/src/main/java/kr/gmtc/tss/util/WebClientConfig.java new file mode 100644 index 0000000..f8d8ee8 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/WebClientConfig.java @@ -0,0 +1,74 @@ +package kr.gmtc.tss.util; + +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.ExchangeStrategies; +import org.springframework.web.reactive.function.client.WebClient; + +import io.netty.channel.ChannelOption; +import io.netty.handler.timeout.ReadTimeoutHandler; +import io.netty.handler.timeout.WriteTimeoutHandler; +import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; + +@Configuration +public class WebClientConfig { + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Bean + public WebClient webClient() { + // 기본 설정으로 생성 + HttpClient httpClient = HttpClient.create(); + + httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000); + httpClient.doOnConnected(connection -> { + connection.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS)); + connection.addHandlerLast(new WriteTimeoutHandler(5000, TimeUnit.MILLISECONDS)); + }); + + //Memory 조정: 2M (default 256KB) + ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() + .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(2*1024*1024)) + .build(); + + return WebClient.builder() + .baseUrl("") + .defaultHeader("Access-Control-Allow-Origin", "*") + .clientConnector(new ReactorClientHttpConnector(httpClient)) + .exchangeStrategies(exchangeStrategies) + .filter( + (req, next) -> next.exchange( + ClientRequest.from(req).header("from", "webclient").build() + ) + ) + .filter( + ExchangeFilterFunction.ofRequestProcessor( + clientRequest -> { + log.info(">>>>>>>>>> REQUEST <<<<<<<<<<"); + log.info("Request: {} {}", clientRequest.method(), clientRequest.url()); + clientRequest.headers().forEach( + (name, values) -> values.forEach(value -> log.info("{} : {}", name, value)) + ); + return Mono.just(clientRequest); + } + ) + ) + .filter( + ExchangeFilterFunction.ofResponseProcessor( + clientResponse -> { + log.info(">>>>>>>>>> RESPONSE <<<<<<<<<<"); + clientResponse.headers().asHttpHeaders().forEach((name, values) -> values.forEach(value -> log.info("{} : {}", name, value))); + return Mono.just(clientResponse); + } + ) + ) + .build(); + } +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/XmlParseUtil.java b/radar/src/main/java/kr/gmtc/tss/util/XmlParseUtil.java new file mode 100644 index 0000000..7664828 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/XmlParseUtil.java @@ -0,0 +1,500 @@ +package kr.gmtc.tss.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import kr.gmtc.tss.util.vo.NodeValue; + + + +public class XmlParseUtil { + + + /** Logger. */ + private static final Logger logger = LoggerFactory.getLogger(XmlParseUtil.class); + + + + + public static Map parseXml(String fileDir) { + + File file = new File(fileDir); + if(file==null||!file.exists()) { + return null; + } + return parseXml(file); + } + + public static Map parseXml(File file) { +// String fileDir="D:\\TEMP\\20200714\\EXCH_ROOT\\CATALOG.XML"; + Map map=null; + + + if(file==null||!file.exists()) { + return map; + } + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = null; + try { + builder = factory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + +// e.printStackTrace(); + logger.error("",e); + } + org.w3c.dom.Document doc = null; + try { + doc = builder.parse(file); + } catch (SAXException | IOException e) { + +// e.printStackTrace(); +// logger.error("",e); + InputStream inputStream = null; + try { + inputStream = new FileInputStream(file.getPath()); + } catch (FileNotFoundException e1) { + + logger.error("",e); + }// Your InputStream from your database. + Reader reader = null; + try { + reader = new InputStreamReader(inputStream, "UTF-8"); + } catch (UnsupportedEncodingException e1) { + + logger.error("",e); + } + + InputSource is = new InputSource(reader); + is.setEncoding("UTF-8"); + try { + doc = builder.parse(is); + } catch (SAXException | IOException e1) { + + logger.error("",e); + } + } + + if(doc==null) { + return map; + } + + NodeList nodeList = doc.getChildNodes(); + + + map=nodeListToMap(nodeList); + +// System.out.println(getNodeValue(map, "S-111_exchangeCatalogue/identiFier/daTe", true)); +// +// System.out.println("content : "+getNodeTextContents(map, "S-111_exchangeCatalogue/identiFier/daTe", true)); +// System.out.println("end"); + return map; + } + + + + + private static String checkNode(String nodePath) { + String firstNode=""; + + if(nodePath.isEmpty()) { + return firstNode; + } + + if(nodePath.indexOf("/")==0) { + nodePath=nodePath.substring(1); + } + firstNode=nodePath; + return firstNode; + } + + private static String getFirstNode(String nodePath) { + String firstNode=""; + + if(nodePath.isEmpty()) { + return firstNode; + } + + if(nodePath.contains("/")) { + String [] nodeNms = nodePath.split("/"); + firstNode=nodeNms[0]; + }else { + firstNode=nodePath; + } + + return firstNode; + + } + + public static String getFirstPath(Map nodeMap) { + String firstNode=""; + + if(nodeMap.isEmpty()) { + return firstNode; + } + + ArrayList keyList=MapUtil.toKeyArray(nodeMap); + + if(keyList.size()>0) { + firstNode=keyList.get(0); + } +// + + return firstNode; + + } + + private static String getOtherNode(String curNode,String nodePath) { + String otherNode=""; + + if(nodePath.isEmpty()) { + return otherNode; + } + + nodePath=checkNode(nodePath); + + if(nodePath.contains("/")||nodePath.equals(curNode)) { + otherNode= nodePath.substring(curNode.length()); + }else { + otherNode=nodePath; + } + + return otherNode; + + } + + + private static String getMapKey(Map nodeMap,String curNode) { + return getMapKey(nodeMap, curNode, true); + } + + + private static String getMapKey(Map nodeMap,String curNode,boolean noCase) { + String mapKey=""; + + if(!noCase) { + return curNode; + }else { + ArrayList list=MapUtil.toKeyArray(nodeMap); + + for (int i = 0; i < list.size(); i++) { + if(list.get(i).toLowerCase().equals(curNode.toLowerCase())) { + mapKey=list.get(i); + } + } + + } + return mapKey; + } + + public static Object getNodeObject(Map nodeMap,String nodePath) { + return getNodeObject(nodeMap, nodePath, true); + } + + public static Object getNodeObject(Map nodeMap,String nodePath,boolean noCase) { + Object nodeValue = null; + try { + + + String checkedNodePath=checkNode(nodePath); + + String curNode=getFirstNode(checkedNodePath); + + String otherNode=getOtherNode(curNode,checkedNodePath); + + if(!curNode.isEmpty()) { + nodeValue= nodeMap.get(getMapKey(nodeMap, curNode, noCase)); + + if(nodeValue!=null) { +// nodeValue=getNodeValue(nodeMap, checkedNodePath, noCase); + String chkdOtherNode=checkNode(otherNode); + if(!chkdOtherNode.isEmpty()) { + nodeValue=getNodeObject(((NodeValue)nodeValue).getChildMap(), otherNode, noCase); + } + + } + + } + } catch (NullPointerException e) { + +// e.printStackTrace(); + logger.error("",e); + } + return nodeValue; + } + + + + public static NodeValue getNodeValue(Map nodeMap,String nodePath) { + return getNodeValue(nodeMap, nodePath, true); + } + + public static NodeValue getNodeValue(Map nodeMap,String nodePath,boolean noCase) { + NodeValue nodeValue = null; + try { + + + String checkedNodePath=checkNode(nodePath); + + String curNode=getFirstNode(checkedNodePath); + + String otherNode=getOtherNode(curNode,checkedNodePath); + + if(!curNode.isEmpty()) { + nodeValue=(NodeValue) nodeMap.get(getMapKey(nodeMap, curNode, noCase)); + + if(nodeValue!=null) { +// nodeValue=getNodeValue(nodeMap, checkedNodePath, noCase); + String chkdOtherNode=checkNode(otherNode); + if(!chkdOtherNode.isEmpty()) { + nodeValue=getNodeValue(nodeValue.getChildMap(), otherNode, noCase); + } + + } + + } + } catch (NullPointerException e) { + +// e.printStackTrace(); + logger.error("",e); + } + return nodeValue; + } + + + public static List getNodeValueList(Map nodeMap,String nodePath) { + return getNodeValueList(nodeMap, nodePath, true); + } + + + public static List getNodeValueList(Map nodeMap,String nodePath,boolean noCase) { + + Object nodeObj=getNodeObject(nodeMap, nodePath, noCase); + + if(nodeObj!=null&&(nodeObj.getClass()==List.class||nodeObj.getClass()==ArrayList.class)) { + return (List )nodeObj; + }else { + List result = new ArrayList<>(); + if(nodeObj!=null) + result.add((NodeValue)nodeObj); + return result; + } + + } + + public static Object getNodeData(Map nodeMap,String nodePath,int category) { + return getNodeData(nodeMap, nodePath, true,category); + } + + public static Object getNodeData(Map nodeMap,String nodePath,boolean noCase,int category) { + NodeValue nodeValue=getNodeValue(nodeMap, nodePath, noCase); + + if(nodeValue!=null) { + //1 : text + //2 : ns + //3 : nodename + //4 : nodeFullname + //5 : ndoeAttr + //6 : nodeChild + switch (category) { + case 2: + return getNodeValue(nodeMap, nodePath, noCase).getNodeNs(); + case 3: + return getNodeValue(nodeMap, nodePath, noCase).getNodeName(); + case 4: + return getNodeValue(nodeMap, nodePath, noCase).getNodeFullName(); + case 5: + return getNodeValue(nodeMap, nodePath, noCase).getAttrMap(); + case 6: + return getNodeValue(nodeMap, nodePath, noCase).getChildMap(); + default: + return getNodeValue(nodeMap, nodePath, noCase).getText(); +// break; + } + }else { + return null; + } + + } + + public static String getNodeTextContents(Map nodeMap,String nodePath) { + return getNodeTextContents(nodeMap, nodePath, true); + } + + public static String getNodeTextContents(Map nodeMap,String nodePath,boolean noCase) { + NodeValue nodeValue=getNodeValue(nodeMap, nodePath, noCase); + + if(nodeValue!=null) { + return getNodeValue(nodeMap, nodePath, noCase).getText(); + }else { + return ""; + } + + } + + public static String getNodeNamespaceNm(Map nodeMap,String nodePath) { + return getNodeNamespaceNm(nodeMap, nodePath, true); + } + + public static String getNodeNamespaceNm(Map nodeMap,String nodePath,boolean noCase) { + NodeValue nodeValue=getNodeValue(nodeMap, nodePath, noCase); + + if(nodeValue!=null) { + return getNodeValue(nodeMap, nodePath, noCase).getNodeNs(); + }else { + return ""; + } + + } + +// public static void main(String[] args) { +// System.out.println("node : "+getFirstNode("/asdfzxxcvzxc/saedf/asdf")); +// } + + + /*public static void main(String[] args) { + String fileDir="D:\\TEMP\\20200714\\EXCH_ROOT\\CATALOG.XML"; + + + Map map=parseXml(fileDir); + +// System.out.println("content : "+getNodeTextContents(map, "S-111_exchangeCatalogue/identiFier/daTe", true)); +// System.out.println("end"); + }*/ + + + + private static NodeValue putNodeData(Map map, Node node) { + NodeValue nodeValue = new NodeValue(node.getNodeName(),node.getTextContent()); + + + if (node.hasAttributes()) { + NamedNodeMap namedNodeMap = node.getAttributes(); + for (int j = 0; j < namedNodeMap.getLength(); j++) { + // System.out.println("NodeNm : "+node.getNodeName()+", Name : + // "+namedNodeMap.item(i).getNodeName()+", Value : + // "+namedNodeMap.item(i).getNodeValue()); + nodeValue.putAttr(namedNodeMap.item(j).getNodeName(), namedNodeMap.item(j).getNodeValue()); + } + } + + + if(map.containsKey(nodeValue.getNodeName())) { + Object data = map.get(nodeValue.getNodeName()); + if(data instanceof List) { + ((List) data).add(nodeValue); + }else { + List valueList = new ArrayList<>(); + //기존데이터 리스트에 입력 + valueList.add((NodeValue) data); + //현재 데이터 입력 + valueList.add(nodeValue); + +// map.put(node.getNodeName(), valueList); + map.put(nodeValue.getNodeName(), valueList); + } + }else { +// map.put(node.getNodeName(), nodeValue); + map.put(nodeValue.getNodeName(), nodeValue); + } + + + return nodeValue; + + + } + + + private static Map nodeListToMap(NodeList nodeList) { + + Map map = new HashMap(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node node = nodeList.item(i); + //#text로 잘못 생성되는 node 제거를 위함 + if("#text".equals(node.getNodeName())||"#comment".equals(node.getNodeName())) + continue; + + NodeValue nodeValue= putNodeData(map, node); + + if(node.hasChildNodes()) { + + nodeValue.setChildMap(nodeListToMap(node.getChildNodes())); + } +// if (x.hasChildNodes() == true) { +// int y = 1; +// String key = x.getNodeName(); +// String tempkey = ""; +// if (map.containsKey(key)) { +// do { +// y++; +// tempkey = key + "_" + y; +// } while (map.containsKey(tempkey) == true); +// map.put(tempkey, x.getTextContent().trim()); +// tempkey = ""; +// } else { +// map.put(key, x.getTextContent().trim()); +// } +// } + } + + return map; + } + + + + public static Map getAllNsOrXsiMap(Map nodeMap,boolean isNsMap){ + Map nsMap = new HashMap<>(); + + try { + + ArrayList list = MapUtil.toKeyArray(nodeMap); + + for (int i = 0; i < list.size(); i++) { + if(nodeMap.get(list.get(i)).getClass()!=NodeValue.class) { + continue; + } + NodeValue nodeValue = (NodeValue) nodeMap.get(list.get(i)); + + if(isNsMap) + nsMap.putAll(nodeValue.getNsMap()); + else + nsMap.putAll(nodeValue.getXsiMap()); + + if (nodeValue.getChildMap() != null) { + nsMap.putAll(getAllNsOrXsiMap(nodeValue.getChildMap(),isNsMap)); + } + } + } catch (NullPointerException e) { + e.printStackTrace(); + } + + return nsMap; + } + + + + +} + diff --git a/radar/src/main/java/kr/gmtc/tss/util/vo/DynamicVO.java b/radar/src/main/java/kr/gmtc/tss/util/vo/DynamicVO.java new file mode 100644 index 0000000..78f50cd --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/vo/DynamicVO.java @@ -0,0 +1,451 @@ +package kr.gmtc.tss.util.vo; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class DynamicVO extends HeaderVO{ + private int mode; + private int rot; + private double sog; + private int posacc; + private int lonInt; + private int latInt; + private double longitude; + private double latitude ; + private double cog; + private int heading; + private String endflag; + private String commState; + private String syncState; + private String slotTimeOut; + private String subMessage; + private String slotInc; + private String numberOfSlot; + private String slotOffSet; + private String keepFlag; + private int naviStatus; + private int specialManoeuve; + private String classBUnit; + private String classBDisplay; + private String classBBand; + private String classBMsg22; + private String classBDSC; + private int modeFlag; + private int raim; + private int isRepeat; + private LocalDateTime bSUTC; + private String bSUTCStr; + private int timeStamp; + private int mSec; + + public DynamicVO() { + mode = 0; + rot = -128; + sog = 1023; + posacc = 0; + lonInt = 108600000; + latInt = 54600000; + longitude = 181.0; + latitude = 91.0; + cog = 3600; + heading = 511; + commState = ""; + syncState = ""; + slotTimeOut = ""; + subMessage = ""; + slotInc = ""; + numberOfSlot = ""; + slotOffSet = ""; + keepFlag = ""; + naviStatus = 15; + specialManoeuve = 0; + classBUnit = ""; + classBDisplay = ""; + classBBand = ""; + classBMsg22 = ""; + classBDSC = ""; + modeFlag = 0; + raim = 0; + isRepeat = 0; + bSUTC = defaultTime(); + bSUTCStr = ""; + timeStamp = 60; + mSec = 0; + } + + public int getMode() { + return mode; + } + + + public void setMode(int mode) { + this.mode = mode; + } + + + public int getRot() { + return rot; + } + + + public void setRot(int rot) { + this.rot = rot; + } + + + public double getSog() { + return sog; + } + + + public void setSog(double sog) { + this.sog = sog; + } + + + public int getPosacc() { + return posacc; + } + + + public void setPosacc(int posacc) { + this.posacc = posacc; + } + + + public int getLonInt() { + return lonInt; + } + + + public void setLonInt(int lonInt) { + this.lonInt = lonInt; + } + + + public int getLatInt() { + return latInt; + } + + + public void setLatInt(int latInt) { + this.latInt = latInt; + } + + + public double getLongitude() { + return longitude; + } + + + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + + public double getLatitude() { + return latitude; + } + + + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + + public double getCog() { + return cog; + } + + + public void setCog(double cog) { + this.cog = cog; + } + + + public int getHeading() { + return heading; + } + + + public void setHeading(int heading) { + this.heading = heading; + } + + + public String getEndflag() { + return endflag; + } + + + public void setEndflag(String endflag) { + this.endflag = endflag; + } + + + public String getCommState() { + return commState; + } + + + public void setCommState(String commState) { + this.commState = commState; + } + + + public String getSyncState() { + return syncState; + } + + + public void setSyncState(String syncState) { + this.syncState = syncState; + } + + + public String getSlotTimeOut() { + return slotTimeOut; + } + + + public void setSlotTimeOut(String slotTimeOut) { + this.slotTimeOut = slotTimeOut; + } + + + public String getSubMessage() { + return subMessage; + } + + + public void setSubMessage(String subMessage) { + this.subMessage = subMessage; + } + + + public String getSlotInc() { + return slotInc; + } + + + public void setSlotInc(String slotInc) { + this.slotInc = slotInc; + } + + + public String getNumberOfSlot() { + return numberOfSlot; + } + + + public void setNumberOfSlot(String numberOfSlot) { + this.numberOfSlot = numberOfSlot; + } + + + public String getSlotOffSet() { + return slotOffSet; + } + + + public void setSlotOffSet(String slotOffSet) { + this.slotOffSet = slotOffSet; + } + + + public String getKeepFlag() { + return keepFlag; + } + + + public void setKeepFlag(String keepFlag) { + this.keepFlag = keepFlag; + } + + + public int getNaviStatus() { + return naviStatus; + } + + + public void setNaviStatus(int naviStatus) { + this.naviStatus = naviStatus; + } + + + public int getSpecialManoeuve() { + return specialManoeuve; + } + + + public void setSpecialManoeuve(int specialManoeuve) { + this.specialManoeuve = specialManoeuve; + } + + + public String getClassBUnit() { + return classBUnit; + } + + + public void setClassBUnit(String classBUnit) { + this.classBUnit = classBUnit; + } + + + public String getClassBDisplay() { + return classBDisplay; + } + + + public void setClassBDisplay(String classBDisplay) { + this.classBDisplay = classBDisplay; + } + + + public String getClassBBand() { + return classBBand; + } + + + public void setClassBBand(String classBBand) { + this.classBBand = classBBand; + } + + + public String getClassBMsg22() { + return classBMsg22; + } + + + public void setClassBMsg22(String classBMsg22) { + this.classBMsg22 = classBMsg22; + } + + + public String getClassBDSC() { + return classBDSC; + } + + + public void setClassBDSC(String classBDSC) { + this.classBDSC = classBDSC; + } + + + public int getModeFlag() { + return modeFlag; + } + + + public void setModeFlag(int modeFlag) { + this.modeFlag = modeFlag; + } + + + public int getRaim() { + return raim; + } + + + public void setRaim(int raim) { + this.raim = raim; + } + + + public int getIsRepeat() { + return isRepeat; + } + + + public void setIsRepeat(int isRepeat) { + this.isRepeat = isRepeat; + } + + + public LocalDateTime getbSUTC() { + return bSUTC; + } + + + public void setbSUTC(LocalDateTime bSUTC) { + this.bSUTC = bSUTC; + } + + + public String getbSUTCStr() { + return bSUTCStr; + } + + + public void setbSUTCStr(String bSUTCStr) { + this.bSUTCStr = bSUTCStr; + } + + + public int getTimeStamp() { + return timeStamp; + } + + + public void setTimeStamp(int timeStamp) { + this.timeStamp = timeStamp; + } + + + public int getmSec() { + return mSec; + } + + + public void setmSec(int mSec) { + this.mSec = mSec; + } + + + public String getString() { + + return "TargetSensor : "+this.targetSensor+"\n"+ + "packetID : "+this.packetID+"\n"+ + "ShipID : "+this.shipID+"\n"+ + "DateTime : "+ this.dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")) +"\n"+ + "AreaID : "+this.areaID+"\n"+ + "MsgType : "+this.msgType+"\n"+ + "DataLength : "+this.dataLength+"\n"+ + "mode : "+String.valueOf(this.mode)+"\n"+ + "rot : "+String.valueOf(this.rot) +"\n"+ + "sog : "+String.valueOf(this.sog) +"\n"+ + "posacc : "+String.valueOf(this.posacc) +"\n"+ + "longitude : "+String.valueOf(this.longitude) +"\n"+ + "latitude : "+String.valueOf(this.latitude) +"\n"+ + "cog : "+String.valueOf(this.cog) +"\n"+ + "heading : "+String.valueOf(this.heading) +"\n"+ + "CommState : "+this.commState +"\n"+ + "SyncState : "+this.syncState +"\n"+ + "SlotTimeOut : "+this.slotTimeOut +"\n"+ + "SubMessage : "+this.subMessage +"\n"+ + "SlotInc : "+this.slotInc +"\n"+ + "NumberOfSlot : "+this.numberOfSlot +"\n"+ + "SlotOffSet : "+this.slotOffSet +"\n"+ + "KeepFlag : "+this.keepFlag +"\n"+ + "NaviStatus : "+String.valueOf(this.naviStatus) +"\n"+ + "SpecialManoeuve : "+String.valueOf(this.specialManoeuve) +"\n"+ + "ClassBUnit : "+this.classBUnit +"\n"+ + "ClassBDisplay : "+this.classBDisplay +"\n"+ + "ClassBBand : "+this.classBBand +"\n"+ + "ClassBMsg22 : "+this.classBMsg22 +"\n"+ + "ClassBDSC : "+this.classBDSC +"\n"+ + "ModeFlag : "+String.valueOf(this.modeFlag) +"\n"+ + "Raim : "+String.valueOf(this.raim) +"\n"+ + "IsRepeat : "+String.valueOf(this.isRepeat) +"\n"+ + "BSUTC : "+this.bSUTC +"\n"+ + "BSUTCStr : "+this.bSUTCStr +"\n"+ + "TimeStamp : "+String.valueOf(this.timeStamp) +"\n"+ + "MSec : "+String.valueOf(this.mSec); + } + + public static LocalDateTime defaultTime() { + return LocalDateTime.of(1899, 12, 30, 00, 00); + } + +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/vo/HeaderVO.java b/radar/src/main/java/kr/gmtc/tss/util/vo/HeaderVO.java new file mode 100644 index 0000000..39b8665 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/vo/HeaderVO.java @@ -0,0 +1,57 @@ +package kr.gmtc.tss.util.vo; + +import java.time.LocalDateTime; + +public class HeaderVO { + protected String targetSensor; + protected String packetID; + protected String shipID; + protected LocalDateTime dateTime; + protected String areaID; + protected String msgType; + protected String dataLength; + + public String getTargetSensor() { + return targetSensor; + } + public void setTargetSensor(String targetSensor) { + this.targetSensor = targetSensor; + } + public String getPacketID() { + return packetID; + } + public void setPacketID(String packetID) { + this.packetID = packetID; + } + public String getShipID() { + return shipID; + } + public void setShipID(String shipID) { + this.shipID = shipID; + } + public LocalDateTime getDateTime() { + return dateTime; + } + public void setDateTime(LocalDateTime dateTime) { + this.dateTime = dateTime; + } + public String getAreaID() { + return areaID; + } + public void setAreaID(String areaID) { + this.areaID = areaID; + } + public String getMsgType() { + return msgType; + } + public void setMsgType(String msgType) { + this.msgType = msgType; + } + public String getDataLength() { + return dataLength; + } + public void setDataLength(String dataLength) { + this.dataLength = dataLength; + } + +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/vo/NodeValue.java b/radar/src/main/java/kr/gmtc/tss/util/vo/NodeValue.java new file mode 100644 index 0000000..5198030 --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/vo/NodeValue.java @@ -0,0 +1,145 @@ +package kr.gmtc.tss.util.vo; + +import java.util.HashMap; +import java.util.Map; + +public class NodeValue{ + + public NodeValue() { + + } + public NodeValue(String nodeFullName,String text) { + + this.text=text; + this.nodeFullName=nodeFullName; + if(!nodeFullName.isEmpty()&&nodeFullName.contains(":")) { + String[] nodeNmArr=nodeFullName.split(":"); + if(nodeNmArr.length>1) { + this.nodeName=nodeNmArr[1]; + this.nodeNs=nodeNmArr[0]; + } + }else { + this.nodeName=nodeFullName; + + } + + + + } + + String nodeFullName; + String nodeName; + String nodeNs=""; + String text; + Map attrMap = new HashMap<>(); + Map childMap = new HashMap<>(); + + Map nsMap = new HashMap<>(); + Map xsiMap = new HashMap<>(); + + public String getText() { + return text; + } + public void setText(String text) { + this.text = text; + } + public Map getAttrMap() { + return attrMap; + } + + public String getAttrMapValue(String key) { + return attrMap.get(key); + } + + + public void setAttrMap(Map attrMap) { + this.attrMap = attrMap; + } + + public void putAttr(String key,String data) { + + if(key.contains("xmlns:")) { + String [] keyVal = key.split(":"); + try { + nsMap.put(keyVal[1], data); + } catch (NullPointerException e) { + nsMap.put(key, data); + } + + }else if(key.contains("xsi:")) { + String [] keyVal = key.split(":"); + try { + xsiMap.put(keyVal[1], data); + } catch (NullPointerException e) { + xsiMap.put(key, data); + } + }else { + attrMap.put(key, data); + } + + + } + + public Map getChildMap() { + return childMap; + } + public void setChildMap(Map childMap) { + this.childMap = childMap; + } + + public void putChildMap(String key,Object data) { + childMap.put(key, data); + } + + + public String getNsMapValue(String key) { + return nsMap.get(key); + } + public Map getNsMap() { + return nsMap; + } + public void setNsMap(Map nsMap) { + this.nsMap = nsMap; + } + + + public String getXsiMapValue(String key) { + return xsiMap.get(key); + } + public Map getXsiMap() { + return xsiMap; + } + public void setXsiMap(Map xsiMap) { + this.xsiMap = xsiMap; + } + public String getNodeName() { + return nodeName; + } + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + public String getNodeNs() { + return nodeNs; + } + public void setNodeNs(String nodeNs) { + this.nodeNs = nodeNs; + } + + + + + public String getNodeFullName() { + return nodeFullName; + } + public void setNodeFullName(String nodeFullName) { + this.nodeFullName = nodeFullName; + } + @Override + public String toString() { + return "NodeValue [nodeName=" + nodeName + ", nodeNs=" + nodeNs + ", text=" + text + ", attrMap=" + attrMap + + ", childMap=" + childMap + "]"; + } + + + +} diff --git a/radar/src/main/java/kr/gmtc/tss/util/vo/StaticVO.java b/radar/src/main/java/kr/gmtc/tss/util/vo/StaticVO.java new file mode 100644 index 0000000..076cc2d --- /dev/null +++ b/radar/src/main/java/kr/gmtc/tss/util/vo/StaticVO.java @@ -0,0 +1,396 @@ +package kr.gmtc.tss.util.vo; + +import java.time.format.DateTimeFormatter; + +public class StaticVO extends HeaderVO{ + private String imo; + private String name; + private String callsign; + private String vmsType; + private int dimA; + private int dimB; + private int dimC; + private int dimD; + private double draught; + private int epfd; + private String etaStr; + private int etaMM; + private int etaDD; + private int etaHH; + private int etaNN; + private String destination; + private int dte; + private int raim; + private int partNo; + private String vender; + private int isRepeat; + private int aisVer; + + public StaticVO() { + imo = ""; + name = ""; + callsign = ""; + vmsType = ""; + dimA = 0; + dimB = 0; + dimC = 0; + dimD = 0; + draught = 0.0; + epfd = 0; + etaStr = ""; + etaMM = 0; + etaDD = 0; + etaHH = 24; + etaNN = 60; + destination = ""; + dte = 1; + raim = 0; + partNo = 0; + vender = ""; + isRepeat = 0; + aisVer = 9; + } + + + + public String getImo() { + return imo; + } + + + + + public void setImo(String imo) { + this.imo = imo; + } + + + + + public String getName() { + return name; + } + + + + + public void setName(String name) { + this.name = name; + } + + + + + public String getCallsign() { + return callsign; + } + + + + + public void setCallsign(String callsign) { + this.callsign = callsign; + } + + + + + public String getVmsType() { + return vmsType; + } + + + + + public void setVmsType(String vmsType) { + this.vmsType = vmsType; + } + + + + + public int getDimA() { + return dimA; + } + + + + + public void setDimA(int dimA) { + this.dimA = dimA; + } + + + + + public int getDimB() { + return dimB; + } + + + + + public void setDimB(int dimB) { + this.dimB = dimB; + } + + + + + public int getDimC() { + return dimC; + } + + + + + public void setDimC(int dimC) { + this.dimC = dimC; + } + + + + + public int getDimD() { + return dimD; + } + + + + + public void setDimD(int dimD) { + this.dimD = dimD; + } + + + + + public double getDraught() { + return draught; + } + + + + + public void setDraught(double draught) { + this.draught = draught; + } + + + + + public int getEpfd() { + return epfd; + } + + + + + public void setEpfd(int epfd) { + this.epfd = epfd; + } + + + + + public String getEtaStr() { + return etaStr; + } + + + + + public void setEtaStr(String etaStr) { + this.etaStr = etaStr; + } + + + + + public int getEtaMM() { + return etaMM; + } + + + + + public void setEtaMM(int etaMM) { + this.etaMM = etaMM; + } + + + + + public int getEtaDD() { + return etaDD; + } + + + + + public void setEtaDD(int etaDD) { + this.etaDD = etaDD; + } + + + + + public int getEtaHH() { + return etaHH; + } + + + + + public void setEtaHH(int etaHH) { + this.etaHH = etaHH; + } + + + + + public int getEtaNN() { + return etaNN; + } + + + + + public void setEtaNN(int etaNN) { + this.etaNN = etaNN; + } + + + + + public String getDestination() { + return destination; + } + + + + + public void setDestination(String destination) { + this.destination = destination; + } + + + + + public int getDte() { + return dte; + } + + + + + public void setDte(int dte) { + this.dte = dte; + } + + + + + public int getRaim() { + return raim; + } + + + + + public void setRaim(int raim) { + this.raim = raim; + } + + + + + public int getPartNo() { + return partNo; + } + + + + + public void setPartNo(int partNo) { + this.partNo = partNo; + } + + + + + public String getVender() { + return vender; + } + + + + + public void setVender(String vender) { + this.vender = vender; + } + + + + + public int getIsRepeat() { + return isRepeat; + } + + + + + public void setIsRepeat(int isRepeat) { + this.isRepeat = isRepeat; + } + + + + + public int getAisVer() { + return aisVer; + } + + + + + public void setAisVer(int aisVer) { + this.aisVer = aisVer; + } + + + + + public String getString() { + return "TargetSensor : "+this.targetSensor+"\n"+ + "packetID : "+this.packetID+"\n"+ + "ShipID : "+this.shipID+"\n"+ + "DateTime : "+this.dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"))+"\n"+ + "AreaID : "+this.areaID+"\n"+ + "MsgType : "+this.msgType+"\n"+ + "DataLength : "+this.dataLength+"\n"+ + "IMO : "+this.imo+"\n"+ + "Name : "+this.name +"\n"+ + "CallSign : "+this.callsign +"\n"+ + "VMSType : "+this.vmsType +"\n"+ + "DimA : "+this.dimA +"\n"+ + "DimB : "+this.dimB +"\n"+ + "DimC : "+this.dimC +"\n"+ + "DimD : "+this.dimD +"\n"+ + "Draught : "+this.draught +"\n"+ + "EPFD : "+this.epfd +"\n"+ + "ETAStr : "+this.etaStr +"\n"+ + "ETAMM : "+this.etaMM +"\n"+ + "ETADD : "+this.etaDD +"\n"+ + "ETAHH : "+this.etaHH +"\n"+ + "ETANN : "+this.etaNN +"\n"+ + "Destination : "+this.destination +"\n"+ + "DTE : "+this.dte +"\n"+ + "Raim : "+this.raim +"\n"+ + "PartNo : "+this.partNo +"\n"+ + "Vender : "+this.vender +"\n"+ + "IsRepeat : "+this.isRepeat +"\n"+ + "AISVer : "+this.aisVer; + } + +} \ No newline at end of file diff --git a/radar/src/main/resources/application.yml b/radar/src/main/resources/application.yml new file mode 100644 index 0000000..a300003 --- /dev/null +++ b/radar/src/main/resources/application.yml @@ -0,0 +1,89 @@ +server: + port: 8090 + +spring: + #main: + #web-application-type: none + db: + #db-type:oracle,mariadb(other - coding more!) + #db-type: oracle + batch-insert-size: 1000 + datasource: + #jdbc-url: jdbc:tibero:thin:@118.220.143.174:18629:SACP_T_DB + jdbc-url: jdbc:tibero:thin:@10.200.31.4:8629:sacp #공항 + driver-class-name: com.tmax.tibero.jdbc.TbDriver + username: UTRACK + password: UTRACK + connectionTimeout: 5000 + maxLifetime: 30000 + + +client: + server: + ip: 127.0.0.1 + port: 8030 + reconn-time-sec: 5 + queue-count: 1000000 + +selep-time-ms: + parse-target: 50 + target-manage: 1 + data-insert: 50 + sql-logger: 50 + + +dynamic-dedupl: + set-size: 50000 + set-remove-unit-size: 5000 + + +process: + #count-log-cron: 0 0/1 * 1/1 * * + #count-log-cron: 0/10 * * 1/1 * * + queue-chunk-size: 1000 + # 매일 오전 9시부터 오후7시까지 1분마다 실행 + # rest api 호출 스케줄러 + rest-cron: 0 0/1 * * * * + # 파일 백업 스케쥴러 시간 + file-backup-cron: 0 0/10 * * * * + # 파일 생성 스케쥴러 시간 + file-make-cron: 0 0/10 * * * * + # 파일 백업 스케쥴러 시간 + data-backup-cron: 0 0/10 * * * * + # 파일 생성 스케쥴러 시간 + data-make-cron: 0 0/10 * * * * + # 스레드 상태 체크 스케줄러 + status-check-cron: 0/10 * * * * * + +flag: + database: false + datafile: true #logstash data log file + file: false #rest api log file + +file-zip-path: ./logs/file +file-zip-bak-path: ./logs/backup +file-make-time: 10 + +data-zip-path: ./logs/data +data-zip-bak-path: ./logs/databackup +data-make-time: 10 + +rest: + server: + ip: 10.200.31.14 + port: 18083 + path: /getRadar/2 + +kafka: + bootstrapServers: http://10.200.31.6:9091,http://10.200.31.8:9091,http://10.200.31.142:9091 #공항 + topic: ic.recv.radar + +classification: 1 #이중화되어 있는 서버의 Index +swclassification: 4 #sw구분 +logclassification: 1 #log구분 + +state: + # 공통코드 CT001의 코드 6자리 + id: LK0503 # 레이더추적정보 + # 1:Primary, 2:Secondary + type: Primary \ No newline at end of file diff --git a/radar/src/main/resources/banner.txt b/radar/src/main/resources/banner.txt new file mode 100644 index 0000000..ffbdd65 --- /dev/null +++ b/radar/src/main/resources/banner.txt @@ -0,0 +1,5 @@ + ______ ____ ____ +/_ __/ / __/ / __/ + / / _\ \ _\ \ +/_/ /___/ /___/ + \ No newline at end of file diff --git a/radar/src/main/resources/logback-spring.xml b/radar/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..9310931 --- /dev/null +++ b/radar/src/main/resources/logback-spring.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + ${LOG_PATTERN} + + + + + + + ${LOG_PATH}/${LOG_FILE_NAME}.log + + ${LOG_PATTERN} + + + + ${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}.log + + 30 + + + + + + + + + %msg%n + + + + ${SQL_LOG_PATH}/${SQL_LOG_FILE_NAME}.%d{yyyy-MM-dd}.log + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/radar/src/main/resources/mybatis-config.xml b/radar/src/main/resources/mybatis-config.xml new file mode 100644 index 0000000..5feae38 --- /dev/null +++ b/radar/src/main/resources/mybatis-config.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/track/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java b/track/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java index 71ba49c..450f1aa 100644 --- a/track/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java +++ b/track/src/main/java/kr/gmtc/tss/data/ParseTargetRunnable.java @@ -137,6 +137,7 @@ public class ParseTargetRunnable implements Runnable { sb.append(t.getSsrCode()); sb.append(","); sb.append(t.getCallsign()); sb.append(","); sb.append(t.getTailNumber()); sb.append(","); + int j = 0; for (BoundingBox b : t.getBbox()) { if (j > 0) sb.append("$"); @@ -145,8 +146,10 @@ public class ParseTargetRunnable implements Runnable { j++; } sb.append(","); - sb.append(t.getAlt()); - + sb.append(t.getAlt()); sb.append(","); + sb.append(t.getSchdulId()); sb.append(","); + sb.append(t.getIsCntrlzone()); + logger.info("logstash 포맷 변환 건수 {}", z++); } diff --git a/track/src/main/java/kr/gmtc/tss/data/vo/TrackVO.java b/track/src/main/java/kr/gmtc/tss/data/vo/TrackVO.java index a54f90e..198b48a 100644 --- a/track/src/main/java/kr/gmtc/tss/data/vo/TrackVO.java +++ b/track/src/main/java/kr/gmtc/tss/data/vo/TrackVO.java @@ -29,8 +29,12 @@ public class TrackVO implements Comparable { private String speed; @JsonProperty("cos") private String course; + @JsonProperty("alt") + private String alt; @JsonProperty("trgt_ty") private String targetType; + @JsonProperty("schdul_id") + private String schdulId; @JsonProperty("mode_s_cd") private String modeSCode; @JsonProperty("ssr_cd") @@ -43,9 +47,11 @@ public class TrackVO implements Comparable { private String correctedLatitude; @JsonProperty("crrct_lon") private String correctedLongitude; + @JsonProperty("is_cntrlzone") + private String isCntrlzone; + private List bbox; - @JsonProperty("alt") - private String alt; + @Override public String toString() { return "{" + @@ -56,12 +62,14 @@ public class TrackVO implements Comparable { ",\"spd\":\"" + speed + "\"" + ",\"cos\":\"" + course + "\"" + ",\"trgt_ty\":\"" + targetType + "\"" + + ",\"schdul_id\":\"" + schdulId + "\"" + ",\"mode_s_cd\":\"" + modeSCode + "\"" + ",\"ssr_cd\":\"" + ssrCode + "\"" + ",\"clsgn\":\"" + callsign + "\"" + ",\"tail_no\":\"" + tailNumber + "\"" + ",\"crrct_lat\":\"" + correctedLatitude + "\"" + ",\"crrct_lon\":\"" + correctedLongitude + "\"" + + ",\"is_cntrlzone\":\"" + isCntrlzone + "\"" + ",\"bbox\":" + bbox.toString() + "}"; } @@ -219,6 +227,22 @@ public class TrackVO implements Comparable { public void setAlt(String alt) { this.alt = alt; } + + public String getSchdulId() { + return schdulId; + } + + public void setSchdulId(String schdulId) { + this.schdulId = schdulId; + } + + public String getIsCntrlzone() { + return isCntrlzone; + } + + public void setIsCntrlzone(String isCntrlzone) { + this.isCntrlzone = isCntrlzone; + } @Override public boolean equals(Object obj) { @@ -310,4 +334,5 @@ public class TrackVO implements Comparable { this.py = py; } } + } diff --git a/track/src/main/resources/application.yml b/track/src/main/resources/application.yml index b349f2d..715af75 100644 --- a/track/src/main/resources/application.yml +++ b/track/src/main/resources/application.yml @@ -79,6 +79,6 @@ logclassification: 1 #log구분 state: # 공통코드 CT001의 코드 6자리 - id: IC0102 # 위치융합정보 + id: IC0109 # 위치융합정보 # 1:Primary, 2:Secondary type: Primary \ No newline at end of file diff --git a/track/src/main/resources/logback-spring.xml b/track/src/main/resources/logback-spring.xml index 6296625..9310931 100644 --- a/track/src/main/resources/logback-spring.xml +++ b/track/src/main/resources/logback-spring.xml @@ -16,7 +16,7 @@ ${LOG_PATTERN} - UTF-8 + @@ -27,7 +27,7 @@ ${LOG_PATTERN} - UTF-8 + @@ -45,7 +45,7 @@ %msg%n - UTF-8 + diff --git a/tss_integrate/.gitignore b/tss_integrate/.gitignore new file mode 100644 index 0000000..5bb4307 --- /dev/null +++ b/tss_integrate/.gitignore @@ -0,0 +1,35 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +/bin + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ +/logs/ diff --git a/tss_integrate/.mvn/wrapper/maven-wrapper.jar b/tss_integrate/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000..c1dd12f Binary files /dev/null and b/tss_integrate/.mvn/wrapper/maven-wrapper.jar differ diff --git a/tss_integrate/.mvn/wrapper/maven-wrapper.properties b/tss_integrate/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..b74bf7f --- /dev/null +++ b/tss_integrate/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar diff --git a/tss_integrate/README.md b/tss_integrate/README.md new file mode 100644 index 0000000..6182709 --- /dev/null +++ b/tss_integrate/README.md @@ -0,0 +1,2 @@ +# TSS + diff --git a/tss_integrate/lib/ipworks-local-1.0.0.jar b/tss_integrate/lib/ipworks-local-1.0.0.jar new file mode 100644 index 0000000..557d507 Binary files /dev/null and b/tss_integrate/lib/ipworks-local-1.0.0.jar differ diff --git a/tss_integrate/lib/state-spring-boot-starter-1.0.3.jar b/tss_integrate/lib/state-spring-boot-starter-1.0.3.jar new file mode 100644 index 0000000..4f5a7df Binary files /dev/null and b/tss_integrate/lib/state-spring-boot-starter-1.0.3.jar differ diff --git a/tss_integrate/lib/tibero-jdbc-7.0.0.jar b/tss_integrate/lib/tibero-jdbc-7.0.0.jar new file mode 100644 index 0000000..69b9029 Binary files /dev/null and b/tss_integrate/lib/tibero-jdbc-7.0.0.jar differ diff --git a/tss_integrate/mvnw b/tss_integrate/mvnw new file mode 100644 index 0000000..8a8fb22 --- /dev/null +++ b/tss_integrate/mvnw @@ -0,0 +1,316 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`\\unset -f command; \\command -v java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/tss_integrate/mvnw.cmd b/tss_integrate/mvnw.cmd new file mode 100644 index 0000000..1d8ab01 --- /dev/null +++ b/tss_integrate/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/tss_integrate/pom.xml b/tss_integrate/pom.xml new file mode 100644 index 0000000..b0e2e3d --- /dev/null +++ b/tss_integrate/pom.xml @@ -0,0 +1,99 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.7.8 + + + kr.gmtc + tss + 0.0.1-SNAPSHOT + TSS + TSS Integrate + + 18 + + 0.0.1-SNAPSHOT + true + + + + org.springframework.boot + spring-boot-starter-quartz + + + org.springframework.boot + spring-boot-starter-web + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 3.0.0 + + + + org.projectlombok + lombok + true + + + + + org.springframework.kafka + spring-kafka + + + + org.springframework.boot + spring-boot-starter-webflux + + + + kr.gmt.so + state-spring-boot-starter + 1.0.3 + system + ${basedir}/lib/state-spring-boot-starter-1.0.3.jar + + + ipworks.local + ipworks-local-1.0.0 + system + 1.0.0 + ${basedir}/lib/ipworks-local-1.0.0.jar + + + + com.tmax.tibero + tibero-jdbc + 7 + system + ${basedir}/lib/tibero-jdbc-7.0.0.jar + + + + + + + EyeTSS_CctvPtz + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + org.projectlombok + lombok + + + + + + + + diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/Application.java b/tss_integrate/src/main/java/kr/gmtc/tss/Application.java new file mode 100644 index 0000000..c534341 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/Application.java @@ -0,0 +1,13 @@ +package kr.gmtc.tss; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/config/TssConfig.java b/tss_integrate/src/main/java/kr/gmtc/tss/config/TssConfig.java new file mode 100644 index 0000000..84775da --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/config/TssConfig.java @@ -0,0 +1,141 @@ +package kr.gmtc.tss.config; + +import java.util.Queue; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import kr.gmtc.tss.data.vo.CctvPtzVO; +import kr.gmtc.tss.util.ArrayBlockingLoggingQueue; + +@Configuration("TssConfig") +public class TssConfig { + + @Value("${kafka.bootstrapServers}") + public String bootstrapServers; + + @Value("${kafka.topic.9}") + public String topic; + + @Value("${kafka.groupId}") + public String consumeGroupId; + + @Value("${file-zip-path}") + public String fileZipPath; + + @Value("${file-zip-bak-path}") + public String fileZipBakPath; + + @Value("${file-make-time}") + public int fileMakeTime; + + @Value("${data-zip-path}") + public String dataZipPath; + + @Value("${data-zip-bak-path}") + public String dataZipBakPath; + + @Value("${data-make-time}") + public int dataMakeTime; + + @Value("${flag.database}") + public boolean flagDataBase; + + @Value("${flag.datafile}") + public boolean flagDataFile; + + @Value("${flag.file}") + public boolean flagFile; + + @Value("${client.queue-count:10000}") + public int queueCount=100000; + + @Value("${spring.db.batch-insert-size:1000}") + public int batchInsertSize; + + @Value("${process.queue-chunk-size:1000}") + public int queueChunkSize; + + @Value("${selep-time-ms.parse-target:50}") + public long parseTargetSleepMs; + + @Value("${selep-time-ms.target-manage:50}") + public long targetManageSleepMs; + + @Value("${selep-time-ms.data-insert:50}") + public long dataInsertSleepMs; + + @Value("${selep-time-ms.sql-logger:50}") + public long sqlLoggerSleepMs; + + @Value("${classification}") + public String classification; + + @Value("${swclassification}") + public String swclassification; + + @Value("${logclassification}") + public String logclassification; + + + public Queue rcvQueue; + public Queue messageBodyQueue; + public Queue dataFileQueue; + + public Queue trackQueue; + + public Queue sqlLogTrackQueue; + + public Queue trackLastQueue; + + public Queue sqlLogTrackLastQueue; + + + @Bean(name = "rcvQueue") + public Queue getRcvQueue() { + this.rcvQueue = new ArrayBlockingLoggingQueue<>(queueCount); + return rcvQueue; + } + + @Bean(name = "messageBodyQueue") + public Queue getMessageBodyQueue() { + this.messageBodyQueue = new ArrayBlockingLoggingQueue<>(queueCount); + return messageBodyQueue; + } + + @Bean(name = "dataFileQueue") + public Queue getDataFileQueue() { + this.dataFileQueue = new ArrayBlockingLoggingQueue<>(queueCount); + return dataFileQueue; + } + + + + @Bean(name = "trackQueue") + public Queue getTrackQueue() { + this.trackQueue = new ArrayBlockingLoggingQueue<>(queueCount); + return trackQueue; + } + + @Bean(name = "trackLastQueue") + public Queue getTrackLastQueue() { + this.trackQueue = new ArrayBlockingLoggingQueue<>(queueCount); + return new ArrayBlockingLoggingQueue<>(queueCount); + } + + @Bean(name = "sqlLogTrackQueue") + public Queue getSqlLogTrackQueue() { + this.trackQueue = new ArrayBlockingLoggingQueue<>(queueCount); + return new ArrayBlockingLoggingQueue<>(queueCount); + } + + @Bean(name = "sqlLogTrackLastQueue") + public Queue getSqlLogTrackLastQueue() { + this.trackQueue = new ArrayBlockingLoggingQueue<>(queueCount); + return new ArrayBlockingLoggingQueue<>(queueCount); + } + + + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/data/CctvPtzParseRunnable.java b/tss_integrate/src/main/java/kr/gmtc/tss/data/CctvPtzParseRunnable.java new file mode 100644 index 0000000..ea03016 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/data/CctvPtzParseRunnable.java @@ -0,0 +1,178 @@ +package kr.gmtc.tss.data; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.tss.data.vo.CctvPtzVO; +import kr.gmtc.tss.status.CountStatus; + +public class CctvPtzParseRunnable implements Runnable { + + private boolean flagFile; + private boolean flagDataBase; + private boolean flagDataFile; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + Queue rcvQueue; + Queue trackQueue; + Queue trackLastQueue; + Queue dataFileQueue; + Queue messageBodyQueue; + + private int rcvPos = 0; + private int rcvStatic = 0; + + private boolean isRunning = false; + private int listChunkSize = 100; + private long sleepMillis; + + private String classification; + private String swclassification; + private String logclassification; + + public CctvPtzParseRunnable(Queue rcvQueue, Queue trackQueue, Queue trackLastQueue + , Queue dataFileQueue,Queue messageBodyQueue, int listChunkSize + , long sleepMillis, boolean flagFile, boolean flagDataBase, boolean flagDataFile + , String classification, String swclassification, String logclassification) { + this.rcvQueue = rcvQueue; + this.trackQueue = trackQueue; + this.trackLastQueue = trackLastQueue; + this.dataFileQueue = dataFileQueue; + this.messageBodyQueue = messageBodyQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + this.flagFile = flagFile; + this.flagDataBase = flagDataBase; + this.flagDataFile = flagDataFile; + this.classification = classification; + this.swclassification = swclassification; + this.logclassification = logclassification; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + + int loopCnt = 0; + if(rcvQueue.size()>listChunkSize) { + loopCnt = listChunkSize; + }else { + loopCnt = rcvQueue.size(); + } + String [] chunkArr = new String[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i] = rcvQueue.poll(); + } + + for (int i = 0; i < chunkArr.length; i++) { + parseAndEnqueue(chunkArr[i]); + } + + } catch (Exception e) { + if (e.getMessage() != null) { + logger.debug("[ParseTarget] Parsing Error Message : " ,e); + } else { + logger.info("[ParserThread] Parsing Error Call Stack" ,e); + } + } + + sleep(sleepMillis); + } + } + + private void parseAndEnqueue(String result) { + try { + ArrayList histroyQueue = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + + Map convert = mapper.readValue(result, new TypeReference>() {}); + ArrayList> list = (ArrayList>) convert.get("data"); + + logger.info("수신 데이터 변환 건수 {}", list.size()); + + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS"); + String dateTime = dateFormat.format(new Date()); + + StringBuilder sb = new StringBuilder(); + + sb.append(dateTime); sb.append(","); + sb.append(logclassification); sb.append(","); //log구분 + sb.append(swclassification); sb.append(","); //sw구분 + sb.append(classification); sb.append("|"); //서버구분 + int i = 0; + int z = 0; + for (LinkedHashMap map : list) { + CctvPtzVO cnvVO = mapper.convertValue(map, CctvPtzVO.class); + + if(flagDataFile) { + if (i > 0) sb.append("^"); + + sb.append(cnvVO.getCam_id()); sb.append(","); + sb.append(cnvVO.getMove()); sb.append(","); + sb.append(cnvVO.getPan()); sb.append(","); + sb.append(cnvVO.getTilt()); sb.append(","); + sb.append(cnvVO.getZoom()); + + logger.info("logstash 포맷 변환 건수 {}", z++); + } + + histroyQueue.add(cnvVO); + i++; + } + + + if(flagFile) { + messageBodyQueue.addAll(histroyQueue); + } + + if(flagDataFile) { + dataFileQueue.add(sb.toString()); + } + + if(flagDataBase) { + if (histroyQueue.size() > 0) { + trackQueue.addAll(histroyQueue); + } + } + + } catch (Exception e) { + logger.error("[ParserThread] Parsing Error Message : " + e.getMessage()); + } + } + + + public synchronized CountStatus getCountAndSetZero() { + CountStatus countStatus = new CountStatus(rcvPos,rcvStatic); + rcvPos = 0; + rcvStatic = 0; + return countStatus; + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[ParseTargetRunnable] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/data/DataInsertRunnable.java b/tss_integrate/src/main/java/kr/gmtc/tss/data/DataInsertRunnable.java new file mode 100644 index 0000000..80b9818 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/data/DataInsertRunnable.java @@ -0,0 +1,86 @@ +package kr.gmtc.tss.data; + +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.tss.data.vo.TrackVO; +import kr.gmtc.tss.db.FusionBatchManager; + +public class DataInsertRunnable implements Runnable { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + Queue trackQueue; + Queue trackLastQueue; + private boolean isRunning = false; + private int batchInsertSize = 1000; + + FusionBatchManager batchInsertManager; + private long sleepMillis; + private String topic; + + public DataInsertRunnable(Queue trackQueue, Queue trackLastQueue, int batchInsertSize, FusionBatchManager batchInsertManager, long sleepMillis, String topic) { + this.trackQueue=trackQueue; + this.trackLastQueue=trackLastQueue; + this.batchInsertSize=batchInsertSize; + this.batchInsertManager=batchInsertManager; + this.sleepMillis=sleepMillis; + this.topic=topic; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + TrackVO [] chunkTrackArr = getChunkTrackArr(trackQueue); + // TrackVO [] chunkTrackLastArr = getChunkTrackArr(trackLastQueue); + if(isRunning) { + if(chunkTrackArr.length > 0) { + batchInsertManager.insertTrackData(chunkTrackArr,topic); + } + + /* + * if(chunkTrackLastArr.length > 0) { + * batchInsertManager.insertTrackLastData(chunkTrackLastArr); } + */ + } + } catch (Exception e) { + e.printStackTrace(); + logger.info("[DataInsertRunnable] Data Insert error : " ,e); + } + + sleep(sleepMillis); + } + } + + private TrackVO [] getChunkTrackArr(Queue sqlQueue) { + int loopCnt=0; + if(sqlQueue.size()>batchInsertSize) { + loopCnt=batchInsertSize; + }else { + loopCnt=sqlQueue.size(); + } + + TrackVO [] chunkArr = new TrackVO[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i]=sqlQueue.poll(); + } + return chunkArr; + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[TargetManager] sleep error : " +e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} \ No newline at end of file diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/data/RuteParseRunnable.java b/tss_integrate/src/main/java/kr/gmtc/tss/data/RuteParseRunnable.java new file mode 100644 index 0000000..f55468d --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/data/RuteParseRunnable.java @@ -0,0 +1,204 @@ +package kr.gmtc.tss.data; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.tss.data.vo.RuteVO; +import kr.gmtc.tss.data.vo.RuteVO.MvPoints; +import kr.gmtc.tss.status.CountStatus; + +public class RuteParseRunnable implements Runnable { + + private boolean flagFile; + private boolean flagDataBase; + private boolean flagDataFile; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + Queue rcvQueue; + Queue trackQueue; + Queue trackLastQueue; + Queue dataFileQueue; + Queue messageBodyQueue; + + private int rcvPos = 0; + private int rcvStatic = 0; + + private boolean isRunning = false; + private int listChunkSize = 100; + private long sleepMillis; + + private String classification; + private String swclassification; + private String logclassification; + + public RuteParseRunnable(Queue rcvQueue, Queue trackQueue, Queue trackLastQueue + , Queue dataFileQueue,Queue messageBodyQueue, int listChunkSize + , long sleepMillis, boolean flagFile, boolean flagDataBase, boolean flagDataFile + , String classification, String swclassification, String logclassification) { + this.rcvQueue = rcvQueue; + this.trackQueue = trackQueue; + this.trackLastQueue = trackLastQueue; + this.dataFileQueue = dataFileQueue; + this.messageBodyQueue = messageBodyQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + this.flagFile = flagFile; + this.flagDataBase = flagDataBase; + this.flagDataFile = flagDataFile; + this.classification = classification; + this.swclassification = swclassification; + this.logclassification = logclassification; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + + int loopCnt = 0; + if(rcvQueue.size()>listChunkSize) { + loopCnt = listChunkSize; + }else { + loopCnt = rcvQueue.size(); + } + String [] chunkArr = new String[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i] = rcvQueue.poll(); + } + + for (int i = 0; i < chunkArr.length; i++) { + parseAndEnqueue(chunkArr[i]); + } + + } catch (Exception e) { + if (e.getMessage() != null) { + logger.debug("[ParseTarget] Parsing Error Message : " ,e); + } else { + logger.info("[ParserThread] Parsing Error Call Stack" ,e); + } + } + + sleep(sleepMillis); + } + } + + private void parseAndEnqueue(String result) { + try { + ArrayList histroyQueue = new ArrayList(); + ObjectMapper mapper = new ObjectMapper(); + + Map convert = mapper.readValue(result, new TypeReference>() {}); + ArrayList> list = (ArrayList>) convert.get("data"); + + logger.info("수신 데이터 변환 건수 {}", list.size()); + + DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss.SSS"); + String dateTime = dateFormat.format(new Date()); + + StringBuilder sb = new StringBuilder(); + + sb.append(dateTime); sb.append(","); + sb.append(logclassification); sb.append(","); //log구분 + sb.append(swclassification); sb.append(","); //sw구분 + sb.append(classification); sb.append("|"); //서버구분 + int i = 0; + int z = 0; + for (LinkedHashMap map : list) { + RuteVO t = mapper.convertValue(map, RuteVO.class); + + if(flagDataFile) { + if (i > 0) sb.append("^"); + + sb.append(t.getMv_id()); sb.append(","); + sb.append(t.getTrgt_id()); sb.append(","); + sb.append(t.getMv_type()); sb.append(","); + sb.append(t.getDep_arr_ty()); sb.append(","); + + int j = 0; + for (MvPoints b : t.getMv_points()) { + if (j > 0) sb.append("$"); + sb.append(b.toDataFormat()); + + j++; + } + + logger.info("logstash 포맷 변환 건수 {}", z++); + } + + histroyQueue.add(t); + i++; + } + + + if(flagFile) { + messageBodyQueue.addAll(histroyQueue); + } + + if(flagDataFile) { + dataFileQueue.add(sb.toString()); + } + + if(flagDataBase) { + if (histroyQueue.size() > 0) { + trackQueue.addAll(histroyQueue); + } + +// if (flagDataBase) { +// histroyQueue +// .stream() +// .collect(Collectors.groupingBy(RuteVO::getTargetId, +// Collectors.maxBy(Comparator.comparing(RuteVO::getReceptionDate)) +// )).forEach((key, value) -> { +// trackLastQueue.add(value.get()); +// });; +// } + } + + } catch (Exception e) { + logger.error("[ParserThread] Parsing Error Message : " + e.getMessage()); + +// e.printStackTrace(); +// if (e.getMessage() != null) { +// logger.debug("[ParserThread] Parsing Error Message : " + e.getMessage()); +// logger.debug("",e); +// } else { +// logger.debug("[ParserThread] Parsing Error Packet Message :" + result); +// } + } + } + + + public synchronized CountStatus getCountAndSetZero() { + CountStatus countStatus = new CountStatus(rcvPos,rcvStatic); + rcvPos = 0; + rcvStatic = 0; + return countStatus; + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[ParseTargetRunnable] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/CctvPtzVO.java b/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/CctvPtzVO.java new file mode 100644 index 0000000..b17c83f --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/CctvPtzVO.java @@ -0,0 +1,115 @@ +package kr.gmtc.tss.data.vo; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CctvPtzVO implements Comparable { + + public long timeStamp = LocalDateTime.now().toInstant(ZoneOffset.ofHours(9)).toEpochMilli(); + + public CctvPtzVO() { + } + + protected LocalDateTime dateTime; + + @JsonProperty("cam_id") + private String cam_id; + @JsonProperty("move") + private String move; + @JsonProperty("pan") + private String pan; + @JsonProperty("tilt") + private String tilt; + @JsonProperty("zoom") + private String zoom; + + @Override + public String toString() { + return "{" + + "\"cam_id\":\"" + cam_id + "\"" + + ",\"move\":\"" + move + "\"" + + ",\"pan\":\"" + pan + "\"" + + ",\"tilt\":\"" + tilt + "\"" + + ",\"zoom\":\"" + zoom + "\"" + + "}"; + } + + + public long getTimeStamp() { + return timeStamp; + } + + + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + + public LocalDateTime getDateTime() { + return dateTime; + } + + + public void setDateTime(LocalDateTime dateTime) { + this.dateTime = dateTime; + } + + + public String getCam_id() { + return cam_id; + } + + + public void setCam_id(String cam_id) { + this.cam_id = cam_id; + } + + + public String getMove() { + return move; + } + + + public void setMove(String move) { + this.move = move; + } + + + public String getPan() { + return pan; + } + + + public void setPan(String pan) { + this.pan = pan; + } + + + public String getTilt() { + return tilt; + } + + + public void setTilt(String tilt) { + this.tilt = tilt; + } + + + public String getZoom() { + return zoom; + } + + + public void setZoom(String zoom) { + this.zoom = zoom; + } + + + @Override + public int compareTo(CctvPtzVO o) { + return 0; + } + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/RuteVO.java b/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/RuteVO.java new file mode 100644 index 0000000..a53e397 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/RuteVO.java @@ -0,0 +1,171 @@ +package kr.gmtc.tss.data.vo; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RuteVO implements Comparable { + + private boolean inserted=false; + + public long timeStamp = LocalDateTime.now().toInstant(ZoneOffset.ofHours(9)).toEpochMilli(); + + public RuteVO() { + } + + protected LocalDateTime dateTime; + + @JsonProperty("mv_id") + private String mv_id; + @JsonProperty("trgt_id") + private String trgt_id; + @JsonProperty("mv_type") + private String mv_type; + @JsonProperty("dep_arr_ty") + private String dep_arr_ty; + + private List mv_points; + + @Override + public String toString() { + return "{" + + "\"mv_id\":\"" + mv_id + "\"" + + ",\"trgt_id\":\"" + trgt_id + "\"" + + ",\"mv_type\":\"" + mv_type + "\"" + + ",\"dep_arr_ty\":\"" + dep_arr_ty + "\"" + + ",\"mv_points\":" + mv_points.toString() + + "}"; + } + + public boolean isInserted() { + return inserted; + } + + public void setInserted(boolean inserted) { + this.inserted = inserted; + } + + public long getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + public LocalDateTime getDateTime() { + return dateTime; + } + + public void setDateTime(LocalDateTime dateTime) { + this.dateTime = dateTime; + } + + public String getMv_id() { + return mv_id; + } + + public void setMv_id(String mv_id) { + this.mv_id = mv_id; + } + + public String getTrgt_id() { + return trgt_id; + } + + public void setTrgt_id(String trgt_id) { + this.trgt_id = trgt_id; + } + + public String getMv_type() { + return mv_type; + } + + public void setMv_type(String mv_type) { + this.mv_type = mv_type; + } + + public String getDep_arr_ty() { + return dep_arr_ty; + } + + public void setDep_arr_ty(String dep_arr_ty) { + this.dep_arr_ty = dep_arr_ty; + } + + public List getMv_points() { + return mv_points; + } + + public void setMv_points(List mv_points) { + this.mv_points = mv_points; + } + + @Override + public boolean equals(Object obj) { + //p1.equals(p2) + if(obj instanceof RuteVO) { + RuteVO p = (RuteVO)obj; + return this.hashCode()==p.hashCode(); + + } + return false; + } + + @Override + public int compareTo(RuteVO o) { + return 0; + } + + public static class MvPoints { + @JsonProperty("spot_sn") + private String spot_sn; + @JsonProperty("lat") + private String lat; + @JsonProperty("lon") + private String lon; + + @Override + public String toString() { + return "{" + + "\"spot_sn\":\"" + spot_sn + "\"" + + ",\"lat\":\"" + lat + "\"" + + ",\"lon\":\"" + lon + "\"" + + "}"; + } + + public String toDataFormat() { + return spot_sn+"@"+lat+"@"+lon; + } + + public String getSpot_sn() { + return spot_sn; + } + + public void setSpot_sn(String spot_sn) { + this.spot_sn = spot_sn; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + public String getLon() { + return lon; + } + + public void setLon(String lon) { + this.lon = lon; + } + + + } + + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/TrackVO.java b/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/TrackVO.java new file mode 100644 index 0000000..a54f90e --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/data/vo/TrackVO.java @@ -0,0 +1,313 @@ +package kr.gmtc.tss.data.vo; + +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class TrackVO implements Comparable { + + private boolean inserted=false; + + public long timeStamp = LocalDateTime.now().toInstant(ZoneOffset.ofHours(9)).toEpochMilli(); + + public TrackVO() { + } + + protected LocalDateTime dateTime; + + @JsonProperty("trgt_id") + private String targetId; + @JsonProperty("recptn_dt") + private String receptionDate; + @JsonProperty("lat") + private String latitude; + @JsonProperty("lon") + private String longitude; + @JsonProperty("spd") + private String speed; + @JsonProperty("cos") + private String course; + @JsonProperty("trgt_ty") + private String targetType; + @JsonProperty("mode_s_cd") + private String modeSCode; + @JsonProperty("ssr_cd") + private String ssrCode; + @JsonProperty("clsgn") + private String callsign; + @JsonProperty("tail_no") + private String tailNumber; + @JsonProperty("crrct_lat") + private String correctedLatitude; + @JsonProperty("crrct_lon") + private String correctedLongitude; + private List bbox; + @JsonProperty("alt") + private String alt; + @Override + public String toString() { + return "{" + + "\"trgt_id\":\"" + targetId + "\"" + + ",\"recptn_dt\":\"" + receptionDate + "\"" + + ",\"lat\":\"" + latitude + "\"" + + ",\"lon\":\"" + longitude + "\"" + + ",\"spd\":\"" + speed + "\"" + + ",\"cos\":\"" + course + "\"" + + ",\"trgt_ty\":\"" + targetType + "\"" + + ",\"mode_s_cd\":\"" + modeSCode + "\"" + + ",\"ssr_cd\":\"" + ssrCode + "\"" + + ",\"clsgn\":\"" + callsign + "\"" + + ",\"tail_no\":\"" + tailNumber + "\"" + + ",\"crrct_lat\":\"" + correctedLatitude + "\"" + + ",\"crrct_lon\":\"" + correctedLongitude + "\"" + + ",\"bbox\":" + bbox.toString() + + "}"; + } + + private boolean lstFlag; + + public boolean isInserted() { + return inserted; + } + + public void setInserted(boolean inserted) { + this.inserted = inserted; + } + + public long getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + public LocalDateTime getDateTime() { + return dateTime; + } + + public void setDateTime(LocalDateTime dateTime) { + this.dateTime = dateTime; + } + + public boolean isLstFlag() { + return lstFlag; + } + + public void setLstFlag(boolean lstFlag) { + this.lstFlag = lstFlag; + } + + public String getTargetId() { + return targetId; + } + + public void setTargetId(String targetId) { + this.targetId = targetId; + } + + public String getReceptionDate() { + return receptionDate; + } + + public void setReceptionDate(String receptionDate) { + this.receptionDate = receptionDate; + } + + public String getLatitude() { + return latitude; + } + + public void setLatitude(String latitude) { + this.latitude = latitude; + } + + public String getLongitude() { + return longitude; + } + + public void setLongitude(String longitude) { + this.longitude = longitude; + } + + public String getSpeed() { + return speed; + } + + public void setSpeed(String speed) { + this.speed = speed; + } + + public String getCourse() { + return course; + } + + public void setCourse(String course) { + this.course = course; + } + + public String getTargetType() { + return targetType; + } + + public void setTargetType(String targetType) { + this.targetType = targetType; + } + + public String getModeSCode() { + return modeSCode; + } + + public void setModeSCode(String modeSCode) { + this.modeSCode = modeSCode; + } + + public String getSsrCode() { + return ssrCode; + } + + public void setSsrCode(String ssrCode) { + this.ssrCode = ssrCode; + } + + public String getCallsign() { + return callsign; + } + + public void setCallsign(String callsign) { + this.callsign = callsign; + } + + public String getTailNumber() { + return tailNumber; + } + + public void setTailNumber(String tailNumber) { + this.tailNumber = tailNumber; + } + + public String getCorrectedLatitude() { + return correctedLatitude; + } + + public void setCorrectedLatitude(String correctedLatitude) { + this.correctedLatitude = correctedLatitude; + } + + public String getCorrectedLongitude() { + return correctedLongitude; + } + + public void setCorrectedLongitude(String correctedLongitude) { + this.correctedLongitude = correctedLongitude; + } + + public List getBbox() { + return bbox; + } + + public void setBbox(List bbox) { + this.bbox = bbox; + } + + public String getAlt() { + return alt; + } + + public void setAlt(String alt) { + this.alt = alt; + } + + @Override + public boolean equals(Object obj) { + //p1.equals(p2) + if(obj instanceof TrackVO) { + TrackVO p = (TrackVO)obj; + return this.hashCode()==p.hashCode(); + + } + return false; + } + + @Override + public int compareTo(TrackVO o) { + return 0; + } + + public static class BoundingBox { + @JsonProperty("cctv_id") + private String cctvId; + @JsonProperty("lt_x") + private String leftTopX; + @JsonProperty("lt_y") + private String leftTopY; + @JsonProperty("rb_x") + private String rightBottomX; + @JsonProperty("rb_y") + private String rightBottomY; + private String px; + private String py; + + @Override + public String toString() { + return "{" + + "\"cctv_id\":\"" + cctvId + "\"" + + ",\"lt_x\":\"" + leftTopX + "\"" + + ",\"lt_y\":\"" + leftTopY + "\"" + + ",\"rb_x\":\"" + rightBottomX + "\"" + + ",\"rb_y\":\"" + rightBottomY + "\"" + + ",\"px\":\"" + px + "\"" + + ",\"py\":\"" + py + "\"" + + "}"; + } + + public String toDataFormat() { + return cctvId+"@"+leftTopX+"@"+leftTopY+"@"+rightBottomX+"@"+rightBottomY+"@"+px+"@"+py; + } + + public String getCctvId() { + return cctvId; + } + public void setCctvId(String cctvId) { + this.cctvId = cctvId; + } + public String getLeftTopX() { + return leftTopX; + } + public void setLeftTopX(String leftTopX) { + this.leftTopX = leftTopX; + } + public String getLeftTopY() { + return leftTopY; + } + public void setLeftTopY(String leftTopY) { + this.leftTopY = leftTopY; + } + public String getRightBottomX() { + return rightBottomX; + } + public void setRightBottomX(String rightBottomX) { + this.rightBottomX = rightBottomX; + } + public String getRightBottomY() { + return rightBottomY; + } + public void setRightBottomY(String rightBottomY) { + this.rightBottomY = rightBottomY; + } + public String getPx() { + return px; + } + public void setPx(String px) { + this.px = px; + } + public String getPy() { + return py; + } + public void setPy(String py) { + this.py = py; + } + } +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/db/DbConfig.java b/tss_integrate/src/main/java/kr/gmtc/tss/db/DbConfig.java new file mode 100644 index 0000000..c60a94b --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/db/DbConfig.java @@ -0,0 +1,36 @@ +package kr.gmtc.tss.db; + +import javax.sql.DataSource; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +public class DbConfig { + + @Bean(name = "dbDataSource") + @ConfigurationProperties(prefix = "spring.db.datasource") + public DataSource db5DataSource() { + + return DataSourceBuilder.create().build(); + } + + @Bean(name="batchSqlSessionFactory") + public SqlSessionFactory batchSqlSessionFactoryBean(@Qualifier("dbDataSource") DataSource batchDataSource, ApplicationContext applicationContext) + throws Exception { + SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); + factoryBean.setDataSource(batchDataSource); + factoryBean.setConfigLocation(applicationContext.getResource("classpath:/mybatis-config.xml")); + return factoryBean.getObject(); + } + +} + diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/db/FusionBatchManager.java b/tss_integrate/src/main/java/kr/gmtc/tss/db/FusionBatchManager.java new file mode 100644 index 0000000..a44f1dd --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/db/FusionBatchManager.java @@ -0,0 +1,553 @@ +package kr.gmtc.tss.db; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.Queue; + +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.tss.data.vo.TrackVO; +import kr.gmtc.tss.main.MainServer; +import kr.gmtc.tss.status.CountStatus; + +public class FusionBatchManager { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private SqlSessionFactory sqlSessionFactory; + private SqlSession session; + + private Queue sqlLogTrackQueue; + private Queue sqlLogTrackLastQueue; + + private int savePos=0; + private int saveLast=0; + private int saveStatic=0; + private int failPos=0; + private int failLast=0; + private int failStatic=0; + + private String topic; + + /** + * mybatis batch insert 속도가 느려서 jdbc 객체를 직접 제어함. + * @param sqlSessionFactory + * @param dbType + */ + public FusionBatchManager(SqlSessionFactory sqlSessionFactory, Queue sqlLogTrackQueue,Queue sqlLogTrackLastQueue) { + this.sqlSessionFactory = sqlSessionFactory; + this.sqlLogTrackQueue = sqlLogTrackQueue; + this.sqlLogTrackLastQueue = sqlLogTrackLastQueue; +// this.dbType=dbType; + openSession(false); + } + + public void openSession(boolean forceOpen) { + if(session==null||forceOpen) + session = sqlSessionFactory.openSession(); + } + + public void closeSession() { + if(session!=null) + session.close(); + } + + public void insertTrackData(TrackVO[] setTrackVOArr, String topic) { + this.topic = topic; + insertTrackData(setTrackVOArr,true); + } + + + private void insertTrackData(TrackVO[] setTrackVOArr, boolean isBatch) { + int fusionFail = 0; + int fusionSave = 0; + int bboxFail = 0; + int bboxSave = 0; + + if(setTrackVOArr==null || setTrackVOArr.length<1) { +// logger.error("insertDataAll - No tableList data"); + logger.debug("insertTrackData(Batch:"+isBatch+") - no data in setTrackVOArr"); + return; + } +// Table destTable=tableList.get(0); + + +// String sql = "INSERT INTO " + destTable.getName() + " (" + getInsertCols(destTable.getColumnList()) + ") " +// + "VALUES (" + getInsertValueParams(destTable.getColumnList()) + ")"; + +// String tableName = "SACP_CCTV_TRACK_" + setTrackVOArr[0].getRecptnDt().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + +// SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd"); +// String now_dt = format.format(setTrackVOArr[0].getRecptnDt()); + +// String tableName = "SACP_TRACK_" + now_dt; + String tableName = "SACP_TRACK_FUSION"; + String sql = "INSERT INTO "+tableName+" (" + + " TRGT_ID, RECPTN_DT, LAT, LON, SPD, COS, TRGT_TY, REVISN_LAT, REVISN_LON, MODE_S_CD, SSR_CD, CLSGN, AC_REG_NO, REGISTER_ID) " + + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + String subTableName = "SACP_FUSION_TRACK_BBOX"; + String subSql = "INSERT INTO "+subTableName+" (" + + " TRGT_ID, RECPTN_DT, CCTV_ID, BBOX_TOP_LEFT_X, BBOX_TOP_LEFT_Y, BBOX_BOTTOM_RIGHT_X, BBOX_BOTTOM_RIGHT_Y, CRDNT_X, CRDNT_Y, REGISTER_ID) " + + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + + PreparedStatement ps=null; + PreparedStatement stmt=null; + Connection con=null; + try { + + con=session.getConnection(); + if(con.isClosed() || !con.isValid(1)) { + closeSession(); + openSession(true); + con=session.getConnection(); + } + con.setAutoCommit(false); + + ps = con.prepareStatement(sql); + stmt = con.prepareStatement(subSql); + for (int i = 0; i < setTrackVOArr.length; i++) { + TrackVO vo = setTrackVOArr[i]; + //입력으로 처리 + //중복 입력 방지를 위함 + vo.setInserted(true); + try { + ps.setString(1, vo.getTargetId()); + ps.setString(2, vo.getReceptionDate()); + ps.setString(3, vo.getLatitude()); + ps.setString(4, vo.getLongitude()); + ps.setString(5, vo.getSpeed()); + ps.setString(6, vo.getCourse()); + ps.setString(7, vo.getTargetType()); + ps.setString(8, vo.getCorrectedLatitude()); + ps.setString(9, vo.getCorrectedLongitude()); + ps.setString(10, vo.getModeSCode()); + ps.setString(11, vo.getSsrCode()); + ps.setString(12, vo.getCallsign()); + ps.setString(13, vo.getTailNumber()); + ps.setString(14, "fusion"); + + ///건별 입력 + if(!isBatch) { + ps.execute(); + savePos++; + fusionSave++; + } + + try { + for (int j = 0; j < vo.getBbox().size(); j++) { + stmt.setString(1, vo.getTargetId()); + stmt.setString(2, vo.getReceptionDate()); + stmt.setString(3, vo.getBbox().get(j).getCctvId()); + stmt.setString(4, vo.getBbox().get(j).getLeftTopX()); + stmt.setString(5, vo.getBbox().get(j).getLeftTopY()); + stmt.setString(6, vo.getBbox().get(j).getRightBottomX()); + stmt.setString(7, vo.getBbox().get(j).getRightBottomY()); + stmt.setString(8, vo.getBbox().get(j).getPx()); + stmt.setString(9, vo.getBbox().get(j).getPy()); + stmt.setString(10, "fusion"); + + ///건별 입력 + if(!isBatch) { + stmt.execute(); + bboxSave++; + } else { + stmt.addBatch(); + } + } + } catch(Exception ex) { + bboxFail++; + throw ex; + } + + //배치 입력 + if(isBatch) { + ps.addBatch(); + } + } catch (Exception e) { + logger.debug("Data Insert error UseSqlLog"); + sqlLogTrackQueue.add(vo); + failPos++; + fusionFail++; + } + + } + + if(isBatch) { + ps.executeBatch(); + stmt.executeBatch(); + //배치 insert는 arr 건수만큼 + //savePos+=setTrackVOArr.length; + //logger.info("savePos 건수"+savePos); + + fusionSave = setTrackVOArr.length - fusionFail; + logger.info("topic {} 배치 저장 건수 {} : 실패 건수 {}", topic, fusionSave, fusionFail); + } else { + logger.info("topic {} 단건 저장 건수 {} : 실패 건수 {}", topic, fusionSave, fusionFail); + } + + con.commit(); + + } catch (Exception e) { + logger.error("insertData(Batch:"+isBatch+") error", e); + if(isBatch) { + logger.error("Try insert row by row"); + insertTrackData(setTrackVOArr, false); + } + + } finally { + + if(ps!=null) { + try { + ps.close(); + } catch (SQLException e) { + logger.error("insertData(Batch:"+isBatch+") PreparedStatement close error",e); + } + } + + if(stmt!=null) { + try { + stmt.close(); + } catch (SQLException e) { + logger.error("insertData(Batch:"+isBatch+") PreparedStatement close error",e); + } + } + if(con!=null) { + try { + con.commit(); + con.setAutoCommit(true); + } catch (SQLException e) { + logger.error("insertData(Batch:"+isBatch+") commit error",e); + } + } + } + } + + public void insertTrackLastData(TrackVO[] setTrackVOArr) { + insertTrackLastData(setTrackVOArr,true); + } + + private void insertTrackLastData(TrackVO[] setTrackLastVOArr, boolean isBatch) { + + if(setTrackLastVOArr == null || setTrackLastVOArr.length<1) { +// logger.error("mergeDynamicLastAll - No tableList data"); + logger.debug("insertTrackLastData(Batch:"+isBatch+") - no data in setTrackVOArr"); + return; + } + + String tableName = "SACP_TRACK_LAST"; + String sql = ""; + + if(MainServer.LAST_DATA_CNT > 0) { + sql = " UPDATE " + tableName + + " SET AC_REG_NO=?, CLSGN=?, SSR_CD=?, MODE_S_CD=?, RECPTN_DT=?, SENSOR_TY=?, CAT_TY=?, LAT=?, LON=?, " + + " SPD=?, COS=?, ALT=?, VIRTL_TRGT_AT=?, TRACK_CRRCT_AT=?, TRACK_CNFDNC=?, CCTV_ID=?, X_CNTS=?, Y_CNTS=?, " + + " UPDUSR_ID=?, UPDT_DT=TO_TIMESTAMP(SYSDATE,'yyyyMMdd')" + + " WHERE TRGT_ID = ?"; + }else { + sql = " INSERT INTO " + tableName + + " ( TRGT_ID, AC_REG_NO, CLSGN, SSR_CD, MODE_S_CD, RECPTN_DT, SENSOR_TY, CAT_TY, " + + " LAT, LON, SPD, COS, ALT, VIRTL_TRGT_AT, TRACK_CRRCT_AT, TRACK_CNFDNC, CCTV_ID, " + + " X_CNTS, Y_CNTS, REGISTER_ID)" + + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + } + + System.out.println("last sql = "+sql); + PreparedStatement ps=null; + Connection con=null; + try { + con=session.getConnection(); + if(con.isClosed() || !con.isValid(1)) { + closeSession(); + openSession(true); + con=session.getConnection(); + } + con.setAutoCommit(false); + +// Statement statement = session.getConnection().createStatement(); + ps = con.prepareStatement(sql); + + for (int i = 0; i < setTrackLastVOArr.length; i++) { + TrackVO vo = setTrackLastVOArr[i]; + //입력으로 처리 + //중복 입력 방지를 위함 + vo.setInserted(true); + + try { + if(MainServer.LAST_DATA_CNT > 0) { + }else { + } + + ///건별 입력 + if(!isBatch) { + ps.execute(); + saveLast++; + + if(MainServer.LAST_DATA_CNT == 0 ) { + MainServer.LAST_DATA_CNT = 1; + } + } + } catch (Exception e) { + logger.debug("Data Insert error UseSqlLog"); + sqlLogTrackLastQueue.add(vo); + failLast++; + } + + //배치 입력 + if(isBatch) { + ps.addBatch(); + } + } + + if(isBatch) { + ps.executeBatch(); + + if(MainServer.LAST_DATA_CNT == 0 ) { + MainServer.LAST_DATA_CNT = 1; + } + + //배치 insert는 arr 건수만큼 + saveLast += setTrackLastVOArr.length; + } + + con.commit(); + + + } catch (Exception e) { + logger.error("trackLast(Batch:"+isBatch+") error", e); + if(isBatch) { + logger.error("Try insert row by row"); + // insertTrackLastData(setTrackLastVOArr, false); + } + + } finally { + + if(ps!=null) { + try { + ps.close(); + } catch (SQLException e) { + logger.error("trackLast(Batch:"+isBatch+") PreparedStatement close error",e); + } + } + if(con!=null) { + try { + con.commit(); + con.setAutoCommit(true); + } catch (SQLException e) { + logger.error("trackLast(Batch:"+isBatch+") commit error",e); + } + } + } + } + public synchronized CountStatus getCountAndSetZero() { + CountStatus countStatus = new CountStatus(savePos, saveLast, saveStatic, failPos, failLast, failStatic); + + savePos = 0; + saveLast = 0; + saveStatic = 0; + failPos = 0; + failLast = 0; + failStatic = 0; + + return countStatus; + } + + /** + * + * 오류 발생시 건/건으로 저장할 수 있도록 수정 + * @param setDynamicVoArr + */ + /*public void insertData(SetDynamicVO[] setDynamicVoArr) { + + if(setDynamicVoArr==null || setDynamicVoArr.length<1) { +// logger.error("insertDataAll - No tableList data"); + logger.debug("insertData - no data in setDynamicVoArr"); + return; + } +// Table destTable=tableList.get(0); + + +// String sql = "INSERT INTO " + destTable.getName() + " (" + getInsertCols(destTable.getColumnList()) + ") " +// + "VALUES (" + getInsertValueParams(destTable.getColumnList()) + ")"; + + String tableName = "th_ais_" + setDynamicVoArr[0].getDateTime().format(DateTimeFormatter.ofPattern("yyyyMMdd")); + + String sql = "INSERT INTO "+tableName +" (" + + " ship_id, recv_dt, lon_val, lat_val, sog_val, cog_val, hdg_val, rot_val, zone_id) " + + " VALUES (?, TO_TIMESTAMP(?,'yyyyMMddhh24miss'), ?, ?, ?, ?, ?, ?, ?)"; + + + PreparedStatement ps=null; + Connection con=null; + try { + + con=session.getConnection(); + if(con.isClosed() || !con.isValid(1)) { + closeSession(); + openSession(true); + con=session.getConnection(); + } + con.setAutoCommit(false); + + +// Statement statement = session.getConnection().createStatement(); + ps = con.prepareStatement(sql); + + for (int i = 0; i < setDynamicVoArr.length; i++) { + SetDynamicVO vo = setDynamicVoArr[i]; + //입력으로 처리 + //중복 입력 방지를 위함 + vo.setInserted(true); + + + try { + + ps.setString(1, vo.getShipID()); + // ps.setDate(2, vo.getDateTime()); + ps.setString(2, vo.getDateTime().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + ps.setDouble(3, vo.getLongitude()); + ps.setDouble(4, vo.getLatitude()); + ps.setDouble(5,vo.getSog()); + ps.setDouble(6,vo.getCog()); + ps.setInt(7, vo.getHeading()); + ps.setInt(8, vo.getRot()); + ps.setString(9, vo.getZoneId()); + // ps.addBatch(); + ps.execute(); + + } catch (Exception e) { +// logger.error("insertData error", e); + + + } + + } +// ps.executeBatch(); + + con.commit(); + + + } catch (Exception e) { + logger.error("insertData error", e); + } finally { + + if(ps!=null) { + try { + ps.close(); + } catch (SQLException e) { + logger.error("insertData PreparedStatement close error",e); + } + } + if(con!=null) { + try { + con.commit(); + con.setAutoCommit(true); + } catch (SQLException e) { + logger.error("insertData commit error",e); + } + } + } + + }*/ + +// /** +// * Insert colums 성성 +// * @param columnList +// * @return +// */ +// private String getInsertCols(List columnList) { +// StringBuilder result=new StringBuilder(); +// for (int i = 0; i < columnList.size(); i++) { +// result.append(columnList.get(i).getName()); +// //마지막에는 ,를 안붙이기 위해 +// if(i!=columnList.size()-1) +// result.append(","); +// } +// return result.toString(); +// } +// +// +// private String getInsertValueParams(List columnList) { +// StringBuilder result=new StringBuilder(); +// for (int i = 0; i < columnList.size(); i++) { +// result.append(setInsertParam(columnList.get(i))); +// //마지막에는 ,를 안붙이기 위해 +// if(i!=columnList.size()-1) +// result.append(","); +// } +// return result.toString(); +// } +// +// /** +// * 파라미터는 ? 로 표현하여 ps.set~~~으로... +// * @param column +// * @return +// */ +// private String setInsertParam(Column column) { +// switch (dbType) { +// case ORACLE: +// return setInsertParamOracle(column); +// default: +// //mariadb default +// return setInsertParamMariadb(column); +// } +// +// +// } +// +// +// private String setInsertParamMariadb(Column column) { +// +// if(column.isCustom()) { +// return column.getCustomStr(); +// }else { +// switch (column.getColumnTypeName()) { +// case "DATE": +// case "DATETIME": +// return "STR_TO_DATE(?,'%Y%m%d%H%i%S')"; +// case "TIMESTAMP": +// case "TIMESTAMP_WITH_TIMEZONE": +// return "STR_TO_DATE(?,'%Y%m%d%H%i%S%f')"; +// case "TIME": +// case "TIME_WITH_TIMEZONE": +// return "STR_TO_DATE(?,'%H%i%S')"; +// default: +// return "?"; +// } +// } +// } +// +// +// +// +// private String setInsertParamOracle(Column column) { +// +// if(column.isCustom()) { +// return column.getCustomStr(); +// }else { +// switch (column.getColumnTypeName()) { +// case "DATE": +// case "DATETIME": +// return "TO_DATE(?,'yyyymmddhh24miss')"; +// case "TIMESTAMP": +// case "TIMESTAMP_WITH_TIMEZONE": +// return "TO_TIMESTAMP(?,'yyyymmddhh24missff')"; +// case "TIME": +// case "TIME_WITH_TIMEZONE": +// return "TO_DATE(?,'hh24miss')"; +// default: +// return "?"; +// } +// } +// +// } + + + + + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/filelog/DataLogger.java b/tss_integrate/src/main/java/kr/gmtc/tss/filelog/DataLogger.java new file mode 100644 index 0000000..165393c --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/filelog/DataLogger.java @@ -0,0 +1,88 @@ +package kr.gmtc.tss.filelog; + +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import kr.gmtc.tss.data.vo.TrackVO; +import kr.gmtc.tss.main.MainServer; +import kr.gmtc.tss.util.FileUtil; + +public class DataLogger implements Runnable { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Queue trackQueue; + private boolean isRunning = true; + private int listChunkSize = 100; + private long sleepMillis; + + public DataLogger(Queue trackQueue, int listChunkSize, long sleepMillis) { + this.trackQueue = trackQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + String [] chunkArr = getChunkMessageArr(trackQueue); + for (int i = 0; i < chunkArr.length; i++) { + FileUtil.writeLogFile(getMessageBody(chunkArr[i]), MainServer.DATA_FILE_NAME); + } + + } catch (Exception e) { + logger.info("-- [SqlLogger] LogSave error : " +e.getLocalizedMessage()); + } + + sleep(sleepMillis); + } + } + + private String [] getChunkMessageArr(Queue trackQueue) { + int loopCnt = 0; + + if(trackQueue.size()>listChunkSize) { + loopCnt = listChunkSize; + }else { + loopCnt = trackQueue.size(); + } + + String [] chunkArr = new String[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i] = trackQueue.poll(); + } + + return chunkArr; + } + + private String getMessageBody(String str) { + StringBuilder sb = new StringBuilder(); + + sb.append(str); + sb.append("\n"); + + return sb.toString(); + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[SqlLogger] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} \ No newline at end of file diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/filelog/MessageBodyLogger.java b/tss_integrate/src/main/java/kr/gmtc/tss/filelog/MessageBodyLogger.java new file mode 100644 index 0000000..fccd703 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/filelog/MessageBodyLogger.java @@ -0,0 +1,103 @@ +package kr.gmtc.tss.filelog; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import kr.gmtc.tss.data.vo.TrackVO; +import kr.gmtc.tss.main.MainServer; +import kr.gmtc.tss.util.FileUtil; + +public class MessageBodyLogger implements Runnable { + +private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private Queue messageBodyQueue; + private boolean isRunning = true; + private int listChunkSize = 100; + private long sleepMillis; + + public MessageBodyLogger(Queue messageBodyQueue, int listChunkSize, long sleepMillis) { + this.messageBodyQueue = messageBodyQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + TrackVO [] chunkArr = getChunkMessageArr(messageBodyQueue); + for (int i = 0; i < chunkArr.length; i++) { + //logger.error(getMessageBody(chunkArr[i])); + FileUtil.writeLogFile(getMessageBody(chunkArr[i]), MainServer.FILE_LOG_NAME); + } + + } catch (Exception e) { + logger.info("-- [SqlLogger] LogSave error : " +e.getLocalizedMessage()); + } + + sleep(sleepMillis); + } + } + + private TrackVO [] getChunkMessageArr(Queue messageBodyQueue) { + int loopCnt = 0; + + if(messageBodyQueue.size()>listChunkSize) { + loopCnt = listChunkSize; + }else { + loopCnt = messageBodyQueue.size(); + } + + TrackVO [] chunkArr = new TrackVO[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i] = messageBodyQueue.poll(); + } + + return chunkArr; + } + +// private String getMessageBody(String str) { +// Date date = new Date(); +// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// +// StringBuilder sb = new StringBuilder(); +// +// sb.append(formatter.format(date)); +// sb.append(" "); +// sb.append(str); +// +// return sb.toString(); +// } + + private String getMessageBody(TrackVO vo) { + ObjectMapper mapper = new ObjectMapper(); + StringBuilder sb = new StringBuilder(); + + sb.append(vo.toString()); + sb.append("\n"); + + return sb.toString(); + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[SqlLogger] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} \ No newline at end of file diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/kafka/KafkaTopicReader.java b/tss_integrate/src/main/java/kr/gmtc/tss/kafka/KafkaTopicReader.java new file mode 100644 index 0000000..0aae941 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/kafka/KafkaTopicReader.java @@ -0,0 +1,55 @@ +package kr.gmtc.tss.kafka; + + +import java.time.Duration; +import java.util.Collections; +import java.util.Properties; +import java.util.Queue; + +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.consumer.ConsumerRecords; +import org.apache.kafka.clients.consumer.KafkaConsumer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KafkaTopicReader implements Runnable { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private final String bootstrapServers; + private final String topic; + private final String consumeGroupId; + + Queue rcvQueue; + + public KafkaTopicReader(String bootstrapServers, String topic, String consumeGroupId, Queue rcvQueue) { + this.bootstrapServers = bootstrapServers; + this.topic = topic; + this.consumeGroupId = consumeGroupId; + this.rcvQueue = rcvQueue; + } + + public void run() { + Properties props = new Properties(); + props.put("bootstrap.servers", bootstrapServers); + props.put("group.id", consumeGroupId); + props.put("auto.offset.reset", "earliest"); + props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); + props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); + try (KafkaConsumer consumer = new KafkaConsumer<>(props)) { + + // 토픽 구독 + consumer.subscribe(Collections.singletonList(topic)); + + while (true) { + ConsumerRecords records = consumer.poll(Duration.ofMillis(100)); + + if (records.count() > 0) logger.info("topic {} 수신 건수 {}", topic, records.count()); + + for (ConsumerRecord record : records) { + rcvQueue.add(record.value()); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/main/MainServer.java b/tss_integrate/src/main/java/kr/gmtc/tss/main/MainServer.java new file mode 100644 index 0000000..5df170f --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/main/MainServer.java @@ -0,0 +1,278 @@ +package kr.gmtc.tss.main; + +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import kr.gmt.so.state.StateManager; +import kr.gmt.so.state.model.SystemState; +import kr.gmtc.tss.data.DataInsertRunnable; +import kr.gmtc.tss.config.TssConfig; +import kr.gmtc.tss.data.CctvPtzParseRunnable; +import kr.gmtc.tss.data.vo.CctvPtzVO; +import kr.gmtc.tss.db.FusionBatchManager; +import kr.gmtc.tss.filelog.DataLogger; +import kr.gmtc.tss.filelog.MessageBodyLogger; +import kr.gmtc.tss.kafka.KafkaTopicReader; +import kr.gmtc.tss.sqllog.SqlLogger; +import kr.gmtc.tss.util.ArrayBlockingLoggingQueue; +import kr.gmtc.tss.util.FileUtil; + +@EnableScheduling +@Component +public class MainServer implements InitializingBean { + + public static String FILE_LOG_NAME; + public static String DATA_FILE_NAME; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + @Qualifier("batchSqlSessionFactory") + public SqlSessionFactory sqlSessionFactory; + private SqlSession session; + + KafkaTopicReader kafkaTopicReader; + CctvPtzParseRunnable parserRunnable; + DataLogger dataLoggerRunnable; + + SqlLogger sqlLoggerRunnable; + FusionBatchManager batchInsertManager; + DataInsertRunnable dataInsertRunnable; + MessageBodyLogger messageBodyLogger; + + List threadList = new ArrayList(); + + // Queue rcvQueue; + // Queue sqlLogTrackQueue; + // Queue sqlLogTrackLastQueue; + + // // track 위치정보 저장 + // Queue trackQueue; + // Queue dataFileQueue; + // Queue trackLastQueue; + + // Queue messageBodyQueue; + + @Autowired + private TssConfig cfg; + + @Autowired + private FileUtil fileUtil; + + @Autowired + private StateManager stateMgr; + private boolean swBeforeStatus = true; + + public static int LAST_DATA_CNT = 0; + + @PostConstruct + public void init() { + + //stateMgr.updateState(); + + logger.info("DataQueue Count : "+cfg.queueCount); + logger.info("flagDataBase : "+cfg.flagDataBase); + logger.info("flagDataFile : "+cfg.flagDataFile); + logger.info("flagFile : "+cfg.flagFile); + + + // rcvQueue=new ArrayBlockingLoggingQueue<>(queueCount); + // sqlLogAsdeTrackQueue=new ArrayBlockingLoggingQueue<>(queueCount); + // sqlLogAsdeTrackLastQueue=new ArrayBlockingLoggingQueue<>(queueCount); + // asdeTrackQueue=new ArrayBlockingLoggingQueue<>(queueCount); + // dataFileQueue=new ArrayBlockingLoggingQueue<>(queueCount); + // asdeTrackLastQueue=new ArrayBlockingLoggingQueue<>(queueCount); + // messageBodyQueue=new ArrayBlockingLoggingQueue<>(queueCount); + + // LAST TABLE 데이터 확인 + // DBLastDataStatus(); + + // 최초 한번만 실행 - 로그파일이 없을 시 생성 + if (cfg.flagFile) FILE_LOG_NAME = fileUtil.createLogFile(cfg.fileZipPath, cfg.fileZipBakPath, cfg.fileMakeTime); // rest log file + if (cfg.flagDataFile) DATA_FILE_NAME = fileUtil.createLogFile(cfg.dataZipPath, cfg.dataZipBakPath, cfg.dataMakeTime); // logstash data file log + } + + @PreDestroy + public void destroy() { + + logger.info("Pre destroy called!!"); + + dataInsertRunnable.setRunning(false); + sqlLoggerRunnable.setRunning(false); + parserRunnable.setRunning(false); + + } + + + @Override + public void afterPropertiesSet() throws Exception { + // if(flagDataBase) startDataInsertThread(); + if(cfg.flagDataFile) startDataLoggerThread(); + // if(cfg.flagFile) startMessageBodyThread(); + + startKafkaThread(); + startParserThread(); + // startSqlLoggerThread(); + } + + @Scheduled(cron = "${process.status-check-cron}") + private void chkThreadStatus() throws InterruptedException{ + + stateMgr.updateState(); + + boolean running = true; + boolean swNewStatus = stateMgr.isActive(); + + // // 이중화 Active / Standby 상태 변경 체크 + // if(swBeforeStatus != swNewStatus){ + + // parserRunnable.setRunning(swNewStatus); + // dataInsertRunnable2.setRunning(swNewStatus); + // dataLoggerRunnable.setRunning(swNewStatus); + // sqlLoggerRunnable.setRunning(swNewStatus); + // messageBodyLogger.setRunning(swNewStatus); + + // } + + // 해당 프로그램이 Active일때 Thread Interrupt 유무 체크 + if(swNewStatus){ + + for(Thread ct : threadList ){ + if(ct.isInterrupted()){ + running = false; + break; + } + } + + if(running){ + stateMgr.updateState(SystemState.Normal); + }else{ + stateMgr.updateState(SystemState.Error); + } + } + + swBeforeStatus = stateMgr.isActive(); + + // logger.info("swBeforeStatus : " + swBeforeStatus); + } + @Scheduled(cron = "${process.file-backup-cron}") + public void fileRecv() throws Exception{ + if (cfg.flagFile) { + /* 파일 압축 */ + fileUtil.createZipFile(cfg.fileZipPath, cfg.fileZipBakPath, cfg.fileMakeTime); + } + } + + @Scheduled(cron = "${process.data-backup-cron}") + public void dataFileRecv() throws Exception{ + if (cfg.flagDataFile) { + /* 파일 압축 */ + fileUtil.createZipFile(cfg.dataZipPath, cfg.dataZipBakPath, cfg.dataMakeTime); + } + } + + // 매 시간 10분 간격 으로 실행 + @Scheduled(cron = "${process.file-make-cron}") + public void fileMake() throws Exception{ + if (cfg.flagFile) { + FILE_LOG_NAME = fileUtil.createLogFile(cfg.fileZipPath, cfg.fileZipBakPath, cfg.fileMakeTime); + } + } + + @Scheduled(cron = "${process.data-make-cron}") + public void dataFileMake() throws Exception{ + if (cfg.flagDataFile) { + DATA_FILE_NAME = fileUtil.createLogFile(cfg.dataZipPath, cfg.dataZipBakPath, cfg.dataMakeTime); + } + } + + + public void startKafkaThread() { + KafkaTopicReader topicReader = new KafkaTopicReader(cfg.bootstrapServers, cfg.topic, cfg.consumeGroupId, cfg.rcvQueue); + this.kafkaTopicReader=topicReader; + + Thread thread = new Thread(topicReader); + thread.start(); + + threadList.add(thread); + } + + public void startParserThread() { + CctvPtzParseRunnable cctvPtzParseRunnable = new CctvPtzParseRunnable(cfg.rcvQueue, cfg.trackQueue, cfg.trackLastQueue, cfg.dataFileQueue, cfg.messageBodyQueue, cfg.queueChunkSize, cfg.parseTargetSleepMs ,cfg.flagFile, cfg.flagDataBase, cfg.flagDataFile, cfg.classification, cfg.swclassification, cfg.logclassification ); + this.parserRunnable=cctvPtzParseRunnable; + Thread thread = new Thread(cctvPtzParseRunnable); + thread.start(); + threadList.add(thread); + cctvPtzParseRunnable.getCountAndSetZero(); + } + + // public void startDataInsertThread() { + // BatchInsertManager batchInsertManager = new BatchInsertManager(sqlSessionFactory, sqlLogTrackQueue,sqlLogTrackLastQueue); + // this.batchInsertManager=batchInsertManager; + + // DataInsertRunnable dataInsertRunnable = new DataInsertRunnable(trackQueue, trackLastQueue, batchInsertSize, batchInsertManager, dataInsertSleepMs, topic); + // this.dataInsertRunnable = dataInsertRunnable; + + // Thread thread = new Thread(dataInsertRunnable); + // thread.start(); + + // threadList.add(thread); + // } + + public void startDataLoggerThread() { + DataLogger dataLoggerRunnable = new DataLogger(cfg.dataFileQueue, cfg.queueChunkSize, cfg.sqlLoggerSleepMs); + this.dataLoggerRunnable = dataLoggerRunnable; + + Thread thread = new Thread(dataLoggerRunnable); + thread.start(); + + threadList.add(thread); + } + + // public void startSqlLoggerThread() { + // SqlLogger sqlLoggerRunnable = new SqlLogger(sqlLogAsdeTrackQueue, sqlLogAsdeTrackLastQueue, queueChunkSize, sqlLoggerSleepMs); + // this.sqlLoggerRunnable = sqlLoggerRunnable; + + // Thread thread = new Thread(sqlLoggerRunnable); + // thread.start(); + + // threadList.add(thread); + // } + + // public void startMessageBodyThread() { + // MessageBodyLogger messageBodyLogger = new MessageBodyLogger(messageBodyQueue, queueChunkSize, sqlLoggerSleepMs); + // this.messageBodyLogger = messageBodyLogger; + + // Thread thread = new Thread(messageBodyLogger); + // thread.start(); + + // threadList.add(thread); + // } + + public void openSession(boolean forceOpen) { + if(session==null||forceOpen) + session = sqlSessionFactory.openSession(); + } + + public void closeSession() { + if(session!=null) + session.close(); + } +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/sqllog/SqlLogger.java b/tss_integrate/src/main/java/kr/gmtc/tss/sqllog/SqlLogger.java new file mode 100644 index 0000000..91f573f --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/sqllog/SqlLogger.java @@ -0,0 +1,132 @@ +package kr.gmtc.tss.sqllog; + +import java.text.SimpleDateFormat; +import java.util.Queue; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import kr.gmtc.tss.data.vo.TrackVO; +import kr.gmtc.tss.main.MainServer; + +public class SqlLogger implements Runnable { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private Queue sqlLogTrackQueue; + private Queue sqlLogTrackLastQueue; + private boolean isRunning=true; + private int listChunkSize= 100; + private long sleepMillis; + + public SqlLogger(Queue sqlLogTrackQueue,Queue sqlLogTrackLastQueue, int listChunkSize, long sleepMillis) { + this.sqlLogTrackQueue = sqlLogTrackQueue; + this.sqlLogTrackLastQueue = sqlLogTrackLastQueue; + this.listChunkSize = listChunkSize; + this.sleepMillis = sleepMillis; + } + + @Override + public void run() { + isRunning = true; + + while (isRunning) { + try { + TrackVO [] chunkArr = getChunkTrackArr(sqlLogTrackQueue); + for (int i = 0; i < chunkArr.length; i++) { + logger.error(getInsertTrackSql(chunkArr[i])); + } + + /* + * chunkArr = getChunkTrackArr(sqlLogTrackLastQueue); for (int i = 0; i < + * chunkArr.length; i++) { logger.error(getInsertLastTrackSql(chunkArr[i])); } + */ + + } catch (Exception e) { + logger.info("-- [SqlLogger] LogSave error : " +e.getLocalizedMessage()); + } + + sleep(sleepMillis); + } + } + + private TrackVO [] getChunkTrackArr(Queue sqlQueue) { + int loopCnt=0; + + if(sqlQueue.size()>listChunkSize) { + loopCnt=listChunkSize; + }else { + loopCnt=sqlQueue.size(); + } + + TrackVO [] chunkArr = new TrackVO[loopCnt]; + + for (int i = 0; i < loopCnt; i++) { + chunkArr[i]=sqlQueue.poll(); + } + + return chunkArr; + } + + private String getInsertTrackSql(TrackVO vo) { + StringBuilder sb = new StringBuilder(); +// sb.append("\n"); + sb.append("INSERT INTO "); + sb.append("SACP_TRACK_FUSION"); + sb.append(" (TRGT_ID, RECPTN_DT, LAT, LON, SPD, COS, TRGT_TY, REVISN_LAT, REVISN_LON, MODE_S_CD, SSR_CD, CLSGN, AC_REG_NO, REGISTER_ID)"); + sb.append("VALUES ("); + sb.append("'"); sb.append(vo.getTargetId()); sb.append("',"); + sb.append("'"); sb.append(vo.getReceptionDate()); sb.append("',"); + sb.append("'"); sb.append(vo.getLatitude()); sb.append("',"); + sb.append("'"); sb.append(vo.getLongitude()); sb.append("',"); + sb.append("'"); sb.append(vo.getSpeed()); sb.append("',"); + sb.append("'"); sb.append(vo.getCourse()); sb.append("',"); + sb.append("'"); sb.append(vo.getTargetType()); sb.append("',"); + sb.append("'"); sb.append(vo.getCorrectedLatitude()); sb.append("',"); + sb.append("'"); sb.append(vo.getCorrectedLongitude()); sb.append("',"); + sb.append("'"); sb.append(vo.getModeSCode()); sb.append("',"); + sb.append("'"); sb.append(vo.getSsrCode()); sb.append("',"); + sb.append("'"); sb.append(vo.getCallsign()); sb.append("',"); + sb.append("'"); sb.append(vo.getTailNumber()); sb.append("',"); + sb.append("'"); sb.append("fusion"); sb.append("');"); + + for (int j = 0; j < vo.getBbox().size(); j++) { + sb.append("\n"); + sb.append("INSERT INTO "); + sb.append("SACP_FUSION_TRACK_BBOX"); + sb.append(" (TRGT_ID, RECPTN_DT, CCTV_ID, BBOX_TOP_LEFT_X, BBOX_TOP_LEFT_Y, BBOX_BOTTOM_RIGHT_X, BBOX_BOTTOM_RIGHT_Y, CRDNT_X, CRDNT_Y, REGISTER_ID)"); + sb.append("VALUES ("); + sb.append("'"); sb.append(vo.getTargetId()); sb.append("',"); + sb.append("'"); sb.append(vo.getReceptionDate()); sb.append("',"); + sb.append("'"); sb.append(vo.getBbox().get(j).getCctvId()); sb.append("',"); + sb.append("'"); sb.append(vo.getBbox().get(j).getLeftTopX()); sb.append("',"); + sb.append("'"); sb.append(vo.getBbox().get(j).getLeftTopY()); sb.append("',"); + sb.append("'"); sb.append(vo.getBbox().get(j).getRightBottomX()); sb.append("',"); + sb.append("'"); sb.append(vo.getBbox().get(j).getRightBottomY()); sb.append("',"); + sb.append("'"); sb.append(vo.getBbox().get(j).getPx()); sb.append("',"); + sb.append("'"); sb.append(vo.getBbox().get(j).getPy()); sb.append("',"); + sb.append("'"); sb.append("fusion"); sb.append("');"); + } + + return sb.toString(); + } + + private String getInsertLastTrackSql(TrackVO vo) { + StringBuilder sb = new StringBuilder(); + if(MainServer.LAST_DATA_CNT > 0) { + sb.append("UPDATE SACP_TRACK_LAST"); + } + + return sb.toString(); + } + + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + logger.debug("[SqlLogger] sleep error : "+e.getLocalizedMessage()); + } + } + + public void setRunning(boolean isRunning) { + this.isRunning = isRunning; + } +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/status/ContextDestroyEventListener.java b/tss_integrate/src/main/java/kr/gmtc/tss/status/ContextDestroyEventListener.java new file mode 100644 index 0000000..44c5242 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/status/ContextDestroyEventListener.java @@ -0,0 +1,8 @@ +package kr.gmtc.tss.status; + +public interface ContextDestroyEventListener { + /** + * Context destroy event handler. + */ + void onDestroy(); +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/status/ContextDestroyStatus.java b/tss_integrate/src/main/java/kr/gmtc/tss/status/ContextDestroyStatus.java new file mode 100644 index 0000000..93b76dc --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/status/ContextDestroyStatus.java @@ -0,0 +1,64 @@ +package kr.gmtc.tss.status; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; +import java.util.ArrayList; +import java.util.List; + +@Component +@Scope("singleton") +public class ContextDestroyStatus { + /** + * Logger. + */ + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * linstener list. + */ + private final List contextDestroyEventListeners = new ArrayList(); + + /** + * context destroy 여부 상태 값. + */ + private boolean shutdown = false; + + /** + * Shutdown flag 설정 등. 등록된 listener의 onDestroy event를 fire 한다. + */ + @PreDestroy + public void destroy() { + logger.info("Called destroy()!"); + shutdown = true; + + for (ContextDestroyEventListener listener : contextDestroyEventListeners) { + listener.onDestroy(); + } + } + + /** + * @return destroy 된다면 true. 동작 중에는 false. + */ + public boolean getShutdownStat() { + return shutdown; + } + public void setShutdownStat(boolean shutdown ) { + this.shutdown=shutdown; +// return shutdown; + } + + + /** + * @param listener + * event fire 대상 class. + */ + public void addListener(final ContextDestroyEventListener listener) { + contextDestroyEventListeners.add(listener); + logger.info("addListener ({}) complete. Listeners count is {}.", listener.getClass().getName(), + contextDestroyEventListeners.size()); + } +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/status/CountStatus.java b/tss_integrate/src/main/java/kr/gmtc/tss/status/CountStatus.java new file mode 100644 index 0000000..8267b72 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/status/CountStatus.java @@ -0,0 +1,240 @@ +package kr.gmtc.tss.status; + +public class CountStatus { + + private int rcvPos=0; + private int rcvStat=0; + private int savePos=0; + private int saveLast=0; + private int saveStatic=0; + private int failPos=0; + private int failLast=0; + private int failStatic=0; + private int exceptPos=0; + + + private int rcvQueueSize=0; + private int dynamicVoQueueSize=0; + private int staticVoQueueSize=0; + private int dynamicInsertQueueSize=0; + private int sqlLogDynamicQueueSize=0; + private int sqlLogDynamicLastQueueSize=0; + private int sqlLogStaticQueueSize=0; + + + + public CountStatus(int rcvPos, int rcvStat) { + this.rcvPos=rcvPos; + this.rcvStat=rcvStat; + } + + public CountStatus(int savePos, int saveLast, int saveStatic, int failPos, int failLast, int failStatic) { + this.savePos=savePos; + this.saveLast=saveLast; + this.saveStatic=saveStatic; + this.failPos=failPos; + this.failLast=failLast; + this.failStatic=failStatic; + } + + public CountStatus() { + + } + + public int getRcvPos() { + return rcvPos; + } + + public void setRcvPos(int rcvPos) { + this.rcvPos = rcvPos; + } + + public int getRcvStat() { + return rcvStat; + } + + public void setRcvStat(int rcvStat) { + this.rcvStat = rcvStat; + } + + public int getSavePos() { + return savePos; + } + + public void setSavePos(int savePos) { + this.savePos = savePos; + } + + public int getSaveLast() { + return saveLast; + } + + public void setSaveLast(int saveLast) { + this.saveLast = saveLast; + } + + public int getSaveStatic() { + return saveStatic; + } + + public void setSaveStatic(int saveStatic) { + this.saveStatic = saveStatic; + } + + public int getFailPos() { + return failPos; + } + + public void setFailPos(int failPos) { + this.failPos = failPos; + } + + public int getFailLast() { + return failLast; + } + + public void setFailLast(int failLast) { + this.failLast = failLast; + } + + public int getFailStatic() { + return failStatic; + } + + public void setFailStatic(int failStatic) { + this.failStatic = failStatic; + } + + public int getExceptPos() { + return exceptPos; + } + + public void setExceptPos(int exceptPos) { + this.exceptPos = exceptPos; + } + + + public int getRcvQueueSize() { + return rcvQueueSize; + } + + public void setRcvQueueSize(int rcvQueueSize) { + this.rcvQueueSize = rcvQueueSize; + } + + public int getDynamicVoQueueSize() { + return dynamicVoQueueSize; + } + + public void setDynamicVoQueueSize(int dynamicVoQueueSize) { + this.dynamicVoQueueSize = dynamicVoQueueSize; + } + + public int getStaticVoQueueSize() { + return staticVoQueueSize; + } + + public void setStaticVoQueueSize(int staticVoQueueSize) { + this.staticVoQueueSize = staticVoQueueSize; + } + + public int getDynamicInsertQueueSize() { + return dynamicInsertQueueSize; + } + + public void setDynamicInsertQueueSize(int dynamicInsertQueueSize) { + this.dynamicInsertQueueSize = dynamicInsertQueueSize; + } + + public int getSqlLogDynamicQueueSize() { + return sqlLogDynamicQueueSize; + } + + public void setSqlLogDynamicQueueSize(int sqlLogDynamicQueueSize) { + this.sqlLogDynamicQueueSize = sqlLogDynamicQueueSize; + } + + public int getSqlLogDynamicLastQueueSize() { + return sqlLogDynamicLastQueueSize; + } + + public void setSqlLogDynamicLastQueueSize(int sqlLogDynamicLastQueueSize) { + this.sqlLogDynamicLastQueueSize = sqlLogDynamicLastQueueSize; + } + + public int getSqlLogStaticQueueSize() { + return sqlLogStaticQueueSize; + } + + public void setSqlLogStaticQueueSize(int sqlLogStaticQueueSize) { + this.sqlLogStaticQueueSize = sqlLogStaticQueueSize; + } + + public void initZero() { + + rcvPos = 0; + rcvStat = 0; + savePos = 0; + saveLast = 0; + saveStatic = 0; + failPos = 0; + failLast = 0; + failStatic = 0; + + } + + public String getCountLog() { + StringBuilder sb = new StringBuilder(); + + sb.append( "\r\n"); + sb.append( "===============================================\r\n" ); + sb.append( " Count Info \r\n" ); + sb.append( "===============================================\r\n" ); + sb.append( " 위치정보 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 수신 / 저장성공 / 저장실패 / 제외 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", rcvPos)+" / "+String.format(" %5s", savePos)+" / "+String.format(" %5s", failPos)+" / "+String.format(" %5s", exceptPos)+"\r\n" ); + sb.append( "===============================================\r\n" ); + sb.append( " 정적정보 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 수신 / 저장성공 / 저장실패 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", rcvStat)+" / "+String.format(" %5s", saveStatic)+" / "+String.format(" %5s", failStatic)+" / \r\n"); + sb.append( "===============================================\r\n");; + sb.append( " 최종위치정보 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 저장성공 / 저장실패 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", saveLast)+" / "+String.format(" %5s", failLast)+" / \r\n"); + sb.append( "===============================================\r\n"); + sb.append( " 큐 상태 \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 수신 / 동적 / 동적(입력) / 정적 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", rcvQueueSize)+" / "+String.format(" %5s", dynamicVoQueueSize)+" / "+String.format(" %5s", dynamicInsertQueueSize)+" / "+String.format(" %5s", staticVoQueueSize)+" / \r\n"); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " SQL \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " 동적 / 최종 / 정적 / \r\n" ); + sb.append( "-----------------------------------------------\r\n" ); + sb.append( " "+String.format(" %5s", sqlLogDynamicQueueSize)+" / "+String.format(" %5s", sqlLogDynamicLastQueueSize)+" / "+String.format(" %5s", sqlLogStaticQueueSize)+" / \r\n"); + sb.append( "===============================================\r\n"); + +// + +// private int rcvQueueSize=0; +// private int dynamicVoQueueSize=0; +// private int staticVoQueueSize=0; +// private int dynamicInsertQueueSize=0; +// private int sqlLogDynamicQueueSize=0; +// private int sqlLogDynamicLastQueueSize=0; +// private int sqlLogStaticQueueSize=0; + + + initZero(); + + return sb.toString(); + } + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/status/CountingComponent.java b/tss_integrate/src/main/java/kr/gmtc/tss/status/CountingComponent.java new file mode 100644 index 0000000..715bfab --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/status/CountingComponent.java @@ -0,0 +1,86 @@ +package kr.gmtc.tss.status; + +import org.springframework.stereotype.Component; + +@Component +public class CountingComponent { + + private int rcvPos=0; + private int rcvStatic=0; + private int savePos=0; + private int failPos=0; + private int saveStatic=0; + private int failStatic=0; + + public int getRcvPos() { + return rcvPos; + } + public void setRcvPos(int rcvPos) { + this.rcvPos = rcvPos; + } + public int getRcvStatic() { + return rcvStatic; + } + public void setRcvStatic(int rcvStatic) { + this.rcvStatic = rcvStatic; + } + public int getSavePos() { + return savePos; + } + public void setSavePos(int savePos) { + this.savePos = savePos; + } + public int getFailPos() { + return failPos; + } + public void setFailPos(int failPos) { + this.failPos = failPos; + } + public int getSaveStatic() { + return saveStatic; + } + public void setSaveStatic(int saveStatic) { + this.saveStatic = saveStatic; + } + public int getFailStatic() { + return failStatic; + } + public void setFailStatic(int failStatic) { + this.failStatic = failStatic; + } + + + + public void initZero() { + rcvPos=0; + rcvStatic=0; + savePos=0; + failPos=0; + saveStatic=0; + failStatic=0; + } + + public String getCountLog() { + String log = "\r\n" + + "===============================================\r\n" + + " Count Info \r\n" + + "===============================================\r\n" + + " 위치정보 \r\n" + + "-----------------------------------------------\r\n" + + " 수신 / 저장성공 / 저장실패 \r\n" + + "-----------------------------------------------\r\n" + + " "+String.format(" %5s", rcvPos)+" / "+String.format(" %5s", savePos)+" / "+String.format(" %5s", failPos)+"\r\n" + + "===============================================\r\n" + + " 정적정보 \r\n" + + "-----------------------------------------------\r\n" + + " 수신 / 저장성공 / 저장실패 \r\n" + + "-----------------------------------------------\r\n" + + " "+String.format(" %5s", rcvStatic)+" / "+String.format(" %5s", saveStatic)+" / "+String.format(" %5s", failStatic)+"\r\n" + + "===============================================\r\n"; + + initZero(); + + return log; + } + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/util/ArrayBlockingLoggingQueue.java b/tss_integrate/src/main/java/kr/gmtc/tss/util/ArrayBlockingLoggingQueue.java new file mode 100644 index 0000000..ec4f2de --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/util/ArrayBlockingLoggingQueue.java @@ -0,0 +1,53 @@ +package kr.gmtc.tss.util; + +import java.util.Collection; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public class ArrayBlockingLoggingQueue extends ArrayBlockingQueue { + + private static Logger logger = LoggerFactory.getLogger(ArrayBlockingLoggingQueue.class); + + public ArrayBlockingLoggingQueue(int capacity, boolean fair, + Collection c) { + super(capacity, fair, c); + // TODO Auto-generated constructor stub + } + + public ArrayBlockingLoggingQueue(int capacity, boolean fair) { + super(capacity, fair); + // TODO Auto-generated constructor stub + } + + public ArrayBlockingLoggingQueue(int capacity) { + super(capacity); + // TODO Auto-generated constructor stub + } + + @Override + public synchronized boolean add(Object e) { + // TODO Auto-generated method stub + logger.debug(e+""); + return super.add(e); + } + + @Override + public synchronized boolean offer(Object e) { + // TODO Auto-generated method stub + logger.debug(e+""); + return super.offer(e); + } + + @Override + public synchronized boolean offer(Object e, long timeout, TimeUnit unit) throws InterruptedException { + // TODO Auto-generated method stub + logger.debug(e+""); + return super.offer(e, timeout, unit); + } + + +} diff --git a/tss_integrate/src/main/java/kr/gmtc/tss/util/FileUtil.java b/tss_integrate/src/main/java/kr/gmtc/tss/util/FileUtil.java new file mode 100644 index 0000000..83d9db1 --- /dev/null +++ b/tss_integrate/src/main/java/kr/gmtc/tss/util/FileUtil.java @@ -0,0 +1,224 @@ +package kr.gmtc.tss.util; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.springframework.stereotype.Component; + +@Component +public class FileUtil { + +// @Value("${file-zip-path}") +// private String fileZipPath; +// +// @Value("${file-zip-bak-path}") +// private String fileZipBakPath; +// +// @Value("${file-make-time}") +// private int fileMakeTime; + +// public static String FILE_LOG_NAME; + + /** + * 로그파일을 압축한다. + * 라이브 데이터 압축을 피하기 위해 20분전 데이터를 압축하는 것으로 세팅 + */ + public void createZipFile(String fileZipPath, String fileZipBakPath, int fileMakeTime) { + + // 압축파일이 저장될 폴더가 존재하는지 확인 + File backDir = new File(fileZipBakPath); + if(!backDir.exists()) { + backDir.mkdirs(); + } + + SimpleDateFormat fileFormatter = new SimpleDateFormat("yyyyMMddHHmm"); + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MINUTE, -20); // 20분전 데이터 확인 + + String time20 = fileFormatter.format(cal.getTime()); + + // 압축할 파일 명 확인. + String bakFileName = "file."+time20+".log"; + + String fileName = ""; + ZipOutputStream zip_out = null; + + // 압축 파일 명 세팅 + StringBuilder sb = new StringBuilder(); + sb.append(bakFileName); + sb.append(".zip"); + fileName = sb.toString(); + + String _path = fileZipPath+"/"+bakFileName; + + File bakFile = new File(_path); + + // 파일이 존재할 경우에만 실행. + if(bakFile.exists()) { + if (fileZipPath.charAt(fileZipPath.length() - 1) != '/') { + _path = _path + "/"; + } + + try { + zip_out = new ZipOutputStream(new FileOutputStream(fileZipBakPath+"/"+fileName)); + zipFolder("", bakFile, zip_out); + zip_out.close(); + + } catch (FileNotFoundException e) { + e.printStackTrace(); + + } catch (IOException e) { + e.printStackTrace(); + + } finally { + + } + } else { + System.out.println("파일이 존재하지 않습니다."); + } + } + + /** + * ZipOutputStream를 넘겨 받아서 하나의 압축파일로 만든다. + * @param parent 상위폴더명 + * @param file 압축할 파일 + * @param zout 압축전체스트림 + * @throws IOException + */ + private void zipFolder(String parent, File file, ZipOutputStream zout) throws IOException { + byte[] data = new byte[2048]; + + int read; + + BufferedInputStream instream = new BufferedInputStream(new FileInputStream(file)); + + ZipEntry zipEntry = new ZipEntry(parent + file.getName()); + zout.putNextEntry(zipEntry); + + while ((read = instream.read(data, 0, 2048)) != -1) { + zout.write(data, 0, read); + } + + zout.flush(); + zout.closeEntry(); + instream.close(); + + file.delete(); // 파일 삭제 + + } + + private void bakFileDelete(String fileZipPath, String date) throws IOException { + File folder = new File(fileZipPath+"/"+date); // file 생성 + + try { + while(folder.exists()){ + File[] files = folder.listFiles(); + + for(File file : files){ + file.delete(); // 하위 파일 삭제 + } + + // 폴더 삭제 + if(files.length == 0 && folder.isDirectory()){ // 하위 파일이 없는지와 폴더인지 확인 후 폴더 삭제 + folder.delete(); // 대상폴더 삭제 + } + } + + } catch(Exception e) { + e.printStackTrace(); + } + } + + /** + * 로그파일을 생성하는 함수 + */ + public String createLogFile(String fileZipPath, String fileZipBakPath, int fileMakeTime) { + File fileDir = new File(fileZipPath); + if(!fileDir.exists()) { + fileDir.mkdirs(); + } + // 현재 시각 중에 분을 구해온다. (minute) + SimpleDateFormat formatter = new SimpleDateFormat("mm"); + String _path = ""; + + Date now = new Date(); + String nowTime = formatter.format(now); + int time = Integer.parseInt(nowTime); + String nowT = ""; + + // 현재 분이 설정한 값의 배수인지 확인한다. + if(time%fileMakeTime == 0){ + if(time == 0) { + nowT = "00"; + }else{ + nowT = String.valueOf(time); + } + }else{ + if(time < fileMakeTime) { + nowT = "00"; + }else{ + nowT = nowTime.substring(0, 1)+"0"; + } + } + + // 생성할 파일명을 설정한다. + SimpleDateFormat fileFormatter = new SimpleDateFormat("yyyyMMddHH"); + String fileTime = fileFormatter.format(now) + nowT; + + try { + _path = fileZipPath+"/file."+fileTime+".log"; + + // static 변수에 값을 세팅한다. + //FILE_LOG_NAME = _path; + + File file = new File(_path); + File parentDir = file.getParentFile(); + if (!parentDir.exists()) { + parentDir.mkdirs(); + } + + if (file.createNewFile()) { + System.out.println("파일 생성 완료"); + } else { + System.out.println("파일 이미 존재"); + } + } catch (IOException e) { + e.printStackTrace(); + } + return _path; + } + + /** + * 파일에 메세지를 쓰는 함수 + * @param msg + * @throws Exception + */ + public static void writeLogFile(String msg, String fileName) throws Exception{ + // File file = new File(FILE_LOG_NAME); + File file = new File(fileName); + + // 파일이 존재할 경우에만 실행 + if(file.exists()) { + FileWriter fw; + try { + fw = new FileWriter(file, true); + fw.write(msg); + fw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + }else { + System.out.println("파일 없음 파일명 확인 필요."); + } + } +} diff --git a/tss_integrate/src/main/resources/application.yml b/tss_integrate/src/main/resources/application.yml new file mode 100644 index 0000000..fb8fdb4 --- /dev/null +++ b/tss_integrate/src/main/resources/application.yml @@ -0,0 +1,86 @@ +server: + port: 8090 + +spring: + #main: + #web-application-type: none + db: + #db-type:oracle,mariadb(other - coding more!) + #db-type: oracle + batch-insert-size: 1000 + datasource: + #jdbc-url: jdbc:tibero:thin:@118.220.143.174:18629:SACP_T_DB + jdbc-url: jdbc:tibero:thin:@10.200.31.4:8629:sacp #공항 + driver-class-name: com.tmax.tibero.jdbc.TbDriver + username: UTRACK + password: UTRACK + connectionTimeout: 5000 + maxLifetime: 30000 + + +client: + server: + ip: 127.0.0.1 + port: 8030 + reconn-time-sec: 5 + queue-count: 1000000 + +selep-time-ms: + parse-target: 50 + target-manage: 1 + data-insert: 50 + sql-logger: 50 + + +dynamic-dedupl: + set-size: 50000 + set-remove-unit-size: 5000 + + +process: + #count-log-cron: 0 0/1 * 1/1 * * + #count-log-cron: 0/10 * * 1/1 * * + queue-chunk-size: 1000 + # 매일 오전 9시부터 오후7시까지 1분마다 실행 + # rest api 호출 스케줄러 + rest-cron: 0 0/1 * * * * + # 파일 백업 스케쥴러 시간 + file-backup-cron: 0 0/10 * * * * + # 파일 생성 스케쥴러 시간 + file-make-cron: 0 0/10 * * * * + # 파일 백업 스케쥴러 시간 + data-backup-cron: 0 0/10 * * * * + # 파일 생성 스케쥴러 시간 + data-make-cron: 0 0/10 * * * * + # 스레드 상태 체크 스케줄러 + status-check-cron: 0/10 * * * * * + +flag: + database: false + datafile: true #logstash data log file, Log 포멧 + file: true #rest api log file, Json + +file-zip-path: ./logs/file +file-zip-bak-path: ./logs/backup +file-make-time: 10 + +data-zip-path: ./logs/data +data-zip-bak-path: ./logs/databackup +data-make-time: 10 + + +kafka: + bootstrapServers: http://10.200.31.6:9091,http://10.200.31.8:9091,http://10.200.31.142:9091 #공항 + groupId: TssTopicReader_TEST + topic: # swclassification 동일하게 번호 설정 + - 9: ic.tracking.ptz + +classification: 1 #이중화되어 있는 서버의 Index +swclassification: 9 #sw구분 +logclassification: 1 #log구분 + +state: + # 공통코드 CT001의 코드 6자리 + id: TEST09 # 위치융합정보 + # 1:Primary, 2:Secondary + type: Primary \ No newline at end of file diff --git a/tss_integrate/src/main/resources/banner.txt b/tss_integrate/src/main/resources/banner.txt new file mode 100644 index 0000000..ffbdd65 --- /dev/null +++ b/tss_integrate/src/main/resources/banner.txt @@ -0,0 +1,5 @@ + ______ ____ ____ +/_ __/ / __/ / __/ + / / _\ \ _\ \ +/_/ /___/ /___/ + \ No newline at end of file diff --git a/tss_integrate/src/main/resources/logback-spring.xml b/tss_integrate/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..6296625 --- /dev/null +++ b/tss_integrate/src/main/resources/logback-spring.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + ${LOG_PATTERN} + UTF-8 + + + + + + ${LOG_PATH}/${LOG_FILE_NAME}.log + + ${LOG_PATTERN} + UTF-8 + + + ${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}.log + + 30 + + + + + + + + + %msg%n + UTF-8 + + + ${SQL_LOG_PATH}/${SQL_LOG_FILE_NAME}.%d{yyyy-MM-dd}.log + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tss_integrate/src/main/resources/mybatis-config.xml b/tss_integrate/src/main/resources/mybatis-config.xml new file mode 100644 index 0000000..5feae38 --- /dev/null +++ b/tss_integrate/src/main/resources/mybatis-config.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + +