shjung 9 ماه پیش
کامیت
2a9a640115
45فایلهای تغییر یافته به همراه2172 افزوده شده و 0 حذف شده
  1. 43 0
      .gitignore
  2. 8 0
      .idea/.gitignore
  3. 20 0
      .idea/gradle.xml
  4. 10 0
      .idea/misc.xml
  5. 124 0
      .idea/uiDesigner.xml
  6. 6 0
      .idea/vcs.xml
  7. 82 0
      build.gradle
  8. BIN
      gradle/wrapper/gradle-wrapper.jar
  9. 6 0
      gradle/wrapper/gradle-wrapper.properties
  10. 234 0
      gradlew
  11. 89 0
      gradlew.bat
  12. 42 0
      its-common/.gitignore
  13. 8 0
      its-common/.idea/.gitignore
  14. 17 0
      its-common/.idea/gradle.xml
  15. 10 0
      its-common/.idea/misc.xml
  16. 6 0
      its-common/.idea/vcs.xml
  17. 39 0
      its-common/build.gradle
  18. BIN
      its-common/gradle/wrapper/gradle-wrapper.jar
  19. 6 0
      its-common/gradle/wrapper/gradle-wrapper.properties
  20. 234 0
      its-common/gradlew
  21. 89 0
      its-common/gradlew.bat
  22. 7 0
      its-common/install.bat
  23. 2 0
      its-common/settings.gradle
  24. 7 0
      its-common/src/main/java/com/its/common/UtilsMain.java
  25. 4 0
      its-common/src/main/java/com/its/common/annotation/DbmsElapsed.java
  26. 4 0
      its-common/src/main/java/com/its/common/annotation/ProcessElapsed.java
  27. 4 0
      its-common/src/main/java/com/its/common/annotation/ScheduleElapsed.java
  28. 360 0
      its-common/src/main/java/com/its/common/utils/ByteUtils.java
  29. 50 0
      its-common/src/main/java/com/its/common/utils/Elapsed.java
  30. 126 0
      its-common/src/main/java/com/its/common/utils/NetUtils.java
  31. 10 0
      its-common/src/main/java/com/its/common/utils/OsPlatform.java
  32. 44 0
      its-common/src/main/java/com/its/common/utils/StringUtils.java
  33. 10 0
      its-common/src/main/java/com/its/common/utils/TestUtils.java
  34. 40 0
      its-network/build.gradle
  35. 7 0
      its-network/install.bat
  36. 7 0
      its-network/src/main/java/com/its/common/NetworkMain.java
  37. 145 0
      its-network/src/main/java/com/its/common/network/NettyUtils.java
  38. 63 0
      its-network/src/main/java/com/its/common/network/tcp/server/NettyServerConfig.java
  39. 80 0
      its-network/src/main/java/com/its/common/network/tcp/server/NettyTcpServer.java
  40. 35 0
      its-network/src/main/java/com/its/common/network/tcp/server/ServerBootstrapFactory.java
  41. 39 0
      its-spring/build.gradle
  42. 7 0
      its-spring/install.bat
  43. 7 0
      its-spring/src/main/java/com/its/common/SpringMain.java
  44. 36 0
      its-spring/src/main/java/com/its/common/spring/SpringUtils.java
  45. 5 0
      settings.gradle

+ 43 - 0
.gitignore

@@ -0,0 +1,43 @@
+.gradle
+logs/
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 20 - 0
.idea/gradle.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleMigrationSettings" migrationVersion="1" />
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleHome" value="" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/its-common" />
+            <option value="$PROJECT_DIR$/its-network" />
+            <option value="$PROJECT_DIR$/its-spring" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 10 - 0
.idea/misc.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="FrameworkDetectionExcludesConfiguration">
+    <file type="web" url="file://$PROJECT_DIR$" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 124 - 0
.idea/uiDesigner.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/its-common" vcs="Git" />
+  </component>
+</project>

+ 82 - 0
build.gradle

@@ -0,0 +1,82 @@
+buildscript {
+    ext {
+        springBootVersion = '2.4.13'
+    }
+    repositories {
+        mavenCentral()
+    }
+    dependencies {
+        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
+        classpath "io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE"
+    }
+
+}
+
+subprojects {
+    group = 'com.its'
+    version = '0.0.1'
+
+    apply plugin: 'java'
+    apply plugin: 'idea'
+    apply plugin: 'org.springframework.boot'
+    apply plugin: 'io.spring.dependency-management'
+
+    sourceCompatibility = '1.8'
+    targetCompatibility = '1.8'
+    compileJava.options.encoding = 'UTF-8'
+
+    repositories {
+        mavenCentral()
+    }
+
+    // 하위 모듈에서 공통으로 사용하는 세팅 추가
+    dependencies {
+//        compileOnly 'org.projectlombok:lombok'
+//        annotationProcessor 'org.projectlombok:lombok'
+//        testAnnotationProcessor 'org.projectlombok:lombok'
+//        testImplementation 'org.projectlombok:lombok'
+
+        implementation 'org.springframework.kafka:spring-kafka'
+
+        // lombok 라이브러리 추가 시작
+        compileOnly 'org.projectlombok:lombok'
+        annotationProcessor 'org.projectlombok:lombok'
+        testCompileOnly 'org.projectlombok:lombok'
+        testAnnotationProcessor 'org.projectlombok:lombok'
+        // lombok 라이브러리 추가 끝
+        testImplementation('org.springframework.boot:spring-boot-starter-test') {
+            exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
+        }
+    }
+
+    test {
+        useJUnitPlatform()
+    }
+}
+
+project(':its-common') {
+    bootJar.enabled = false
+    jar.enabled = true
+    dependencies {
+    }
+}
+
+project(':its-spring') {
+    bootJar.enabled = false
+    jar.enabled = true
+    dependencies {
+        implementation 'org.springframework.boot:spring-boot-starter-web'
+
+        testImplementation 'org.springframework.boot:spring-boot-starter-test'
+    }
+}
+
+project(':its-network') {
+    bootJar.enabled = false
+    jar.enabled = true
+    dependencies {
+        implementation 'org.springframework.boot:spring-boot-starter-web'
+
+        testImplementation 'org.springframework.boot:spring-boot-starter-test'
+    }
+}

BIN
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Fri Oct 11 10:36:45 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 234 - 0
gradlew

@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed 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.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+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
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 89 - 0
gradlew.bat

@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem 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, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 42 - 0
its-common/.gitignore

@@ -0,0 +1,42 @@
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store

+ 8 - 0
its-common/.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 17 - 0
its-common/.idea/gradle.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleMigrationSettings" migrationVersion="1" />
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="gradleHome" value="" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 10 - 0
its-common/.idea/misc.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="FrameworkDetectionExcludesConfiguration">
+    <file type="web" url="file://$PROJECT_DIR$" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 6 - 0
its-common/.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>

+ 39 - 0
its-common/build.gradle

@@ -0,0 +1,39 @@
+plugins {
+    id 'java'
+}
+
+group = 'com.its'
+version = '0.0.1'
+
+sourceCompatibility = '1.8'
+targetCompatibility = '1.8'
+compileJava.options.encoding = 'UTF-8'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+}
+
+processResources {
+    enabled = false
+}
+
+jar {
+    enabled = true
+}
+
+test {
+    useJUnitPlatform()
+}
+
+task runInstallJarLibrary(type:Exec) {
+    doFirst {
+        println "its-common library install mvn repository..."
+        workingDir = file('.')
+        commandLine = ['cmd', '/C', 'start', 'install.bat']
+        // cmd /C start ./install.bat
+    }
+}
+jar.finalizedBy runInstallJarLibrary

BIN
its-common/gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
its-common/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Thu Oct 10 15:54:06 KST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 234 - 0
its-common/gradlew

@@ -0,0 +1,234 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed 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.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+APP_NAME="Gradle"
+APP_BASE_NAME=${0##*/}
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+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
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+# Collect all arguments for the java command;
+#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+#     shell script including quotes and variable substitutions, so put them in
+#     double quotes to make sure that they get re-expanded; and
+#   * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 89 - 0
its-common/gradlew.bat

@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem 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, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 7 - 0
its-common/install.bat

@@ -0,0 +1,7 @@
+@echo off
+chcp 65001
+@echo on
+copy build\libs\its-common-0.0.1.jar c:\java\repository\
+cd C:\java\apache-maven-3.9.6\bin
+cd C:\Users\OpenValue\.m2\wrapper\dists\apache-maven-3.6.3-bin\1iopthnavndlasol9gbrbg6bf2\apache-maven-3.6.3\bin
+.\mvn install:install-file -Dfile="C:\java\repository\its-common-0.0.1.jar" -DgroupId=com.its -DartifactId=its-common -Dversion=0.0.1 -Dpackaging=jar -DlocalRepositoryPath=C:\java\repository\

+ 2 - 0
its-common/settings.gradle

@@ -0,0 +1,2 @@
+rootProject.name = 'its-common'
+

+ 7 - 0
its-common/src/main/java/com/its/common/UtilsMain.java

@@ -0,0 +1,7 @@
+package com.its.common;
+
+public class UtilsMain {
+    public static void main(String[] args) {
+        System.out.printf("com.its.common.utils!");
+    }
+}

+ 4 - 0
its-common/src/main/java/com/its/common/annotation/DbmsElapsed.java

@@ -0,0 +1,4 @@
+package com.its.common.annotation;
+
+public @interface DbmsElapsed {
+}

+ 4 - 0
its-common/src/main/java/com/its/common/annotation/ProcessElapsed.java

@@ -0,0 +1,4 @@
+package com.its.common.annotation;
+
+public @interface ProcessElapsed {
+}

+ 4 - 0
its-common/src/main/java/com/its/common/annotation/ScheduleElapsed.java

@@ -0,0 +1,4 @@
+package com.its.common.annotation;
+
+public @interface ScheduleElapsed {
+}

+ 360 - 0
its-common/src/main/java/com/its/common/utils/ByteUtils.java

@@ -0,0 +1,360 @@
+package com.its.common.utils;
+
+public class ByteUtils {
+
+	private ByteUtils() {}
+
+	private static final int[] BYTE_MASKED_ARRAY = { 1, 2, 4, 8, 16, 32, 64, 128 };
+
+	public static short getShort(byte[] data, int start) {
+		return (short)(data[start  ] << 8 |
+				       data[start+1] & 0xFF);
+	}
+	public static short getShortLE(byte[] data, int start) {
+		return (short)(data[start+1] << 8 |
+				       data[start  ] & 0xFF);
+	}
+	public static int getUnsignedShort(byte[] data, int start) {
+		return data[start] << 8 & 0xFF00 | data[start+1] & 0x00FF;
+	}
+	public static int getUnsignedShortLE(byte[] data, int start) {
+		return data[start+1] << 8 & 0xFF00 | data[start] & 0x00FF;
+	}
+
+	public static int getInt(byte[] data, int start) {
+		return data[start] << 24 & 0xFF000000 | data[start+1] << 16 & 0x00FF0000 | data[start+2] << 8 & 0x0000FF00 | data[start+3] & 0x000000FF;
+	}
+	public static int getIntLE(byte[] data, int start) {
+		return data[start+3] << 24 & 0xFF000000 | data[start+2] << 16 & 0x00FF0000 | data[start+1] << 8 & 0x0000FF00 | data[start] & 0x000000FF;
+	}
+	public static long getUnsignedInt(byte[] data, int start) {
+		return (long)(data[start] << 24 & 0xFF000000 | data[start+1] << 16 & 0x00FF0000 | data[start+2] << 8 & 0x0000FF00 | data[start+3] & 0x000000FF);
+	}
+	public static long getUnsignedIntLE(byte[] data, int start) {
+		return (long)(data[start+3] << 24 & 0xFF000000 | data[start+2] << 16 & 0x00FF0000 | data[start+1] << 8 & 0x0000FF00 | data[start] & 0x000000FF);
+	}
+
+	public static void setUnsignedInt(byte[] data, int start, long val) {
+		data[start  ] = (byte)((val >> 24) & 0x000000FF);
+		data[start+1] = (byte)((val >> 16) & 0x000000FF);
+		data[start+2] = (byte)((val >> 8 ) & 0x000000FF);
+		data[start+3] = (byte)((val      ) & 0x000000FF);
+	}
+
+	public static void setUnsignedShort(byte[] data, int start, int val) {
+		data[start  ] = (byte)((val >> 8 ) & 0x000000FF);
+		data[start+1] = (byte)((val      ) & 0x000000FF);
+	}
+
+	public static void setUnsignedIntLE(byte[] data, int start, long val) {
+		data[start+3] = (byte)((val >> 24) & 0x000000FF);
+		data[start+2] = (byte)((val >> 16) & 0x000000FF);
+		data[start+1] = (byte)((val >> 8 ) & 0x000000FF);
+		data[start  ] = (byte)((val      ) & 0x000000FF);
+	}
+
+	public static void setUnsignedShortLE(byte[] data, int start, int val) {
+		data[start+1] = (byte)((val >> 8 ) & 0x000000FF);
+		data[start  ] = (byte)((val      ) & 0x000000FF);
+	}
+
+	public static int byteToInt(byte srcValue)
+	{
+		return srcValue & 0xFF;
+	}
+
+	public static int shortToInt(short srcValue)
+	{
+		return srcValue & 0xFFFF;
+	}
+
+	public static long intToLong(int srcValue)
+	{
+		return (long)(srcValue & 0xFFFFFFFF);
+	}
+
+	public static int longToInt(long srcValue)
+	{
+		return (int)(srcValue & 0xFFFFFFFF);
+	}
+
+	public static String byteToBitString(byte srcValue) {
+		return String.format("%8s", Long.toBinaryString(srcValue & 0xFF)).replace(' ', '0');
+	}
+
+	public static String shortToBitString(short srcValue) {
+		return String.format("%16s", Long.toBinaryString(srcValue & 0xFF)).replace(' ', '0');
+	}
+
+	public static String intToBitString(int srcValue) {
+		return String.format("%32s", Integer.toBinaryString(srcValue & 0xFF)).replace(' ', '0');
+	}
+
+	public static String longToBitString(long srcValue)
+	{
+		return String.format("%64s", Long.toBinaryString(srcValue & 0xFF)).replace(' ', '0');
+	}
+
+	public static int extractBits(byte srcValue, int beginBitDigit, int endBitDigit) {
+		int maskedValue = 0;
+		for (int idx = beginBitDigit; idx <= endBitDigit; idx++) {
+			maskedValue += BYTE_MASKED_ARRAY[idx];
+		}
+		return (srcValue & maskedValue) >> beginBitDigit;
+	}
+
+	public static int extractBit(byte srcValue, int bitDigit) {
+		return (srcValue & BYTE_MASKED_ARRAY[bitDigit]) == BYTE_MASKED_ARRAY[bitDigit] ? 1 : 0;
+	}
+
+	public static int compareMaskedValue(byte srcValue, int maskValue, int compareValue) {
+		int resultValue = byteToInt(srcValue) & maskValue;
+		return resultValue == compareValue ? 0 : resultValue > compareValue ? 1 : -1;
+	}
+
+	public static String convertCustomDateTime(String strDate)
+	{
+		String convertDate = strDate;
+		if (convertDate.lastIndexOf(".") != -1) {
+			convertDate = convertDate.substring(0, convertDate.lastIndexOf("."));
+		}
+		return convertDate.replaceAll("-", "").replaceAll(":", "").replaceAll(" ", "");
+	}
+
+	public static byte[] hexToByteArray(String hex)
+	{
+		if ((hex == null) || (hex.length() == 0)) {
+			return null;
+		}
+		byte[] ba = new byte[hex.length() / 2];
+		for (int i = 0; i < ba.length; i++) {
+			ba[i] = ((byte)Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16));
+		}
+		return ba;
+	}
+
+	public static String byteArrayToHex(byte[] aData) {
+		if (aData != null && aData.length != 0) {
+			int dataLength = aData.length;
+			int line = dataLength / 16;
+			StringBuffer sb = new StringBuffer(dataLength * 3 + line);
+			sb.append("\r\n");
+
+			for(int ii = 0; ii < dataLength; ii += 16) {
+				for(int jj = 0; jj < 16; ++jj) {
+					int pos = ii + jj;
+					if (pos >= dataLength) {
+						break;
+					}
+
+					String hexNumber = "0" + Integer.toHexString(255 & aData[pos]).toUpperCase();
+					sb.append(hexNumber.substring(hexNumber.length() - 2));
+					sb.append(" ");
+				}
+
+				sb.append("\r\n");
+			}
+			return sb.toString();
+		}
+		return "";
+	}
+
+	public static byte[] intToShortBytes(int length) {
+		byte[] b3 = new byte[2];
+		if (length > 255)
+		{
+			b3[0] = ((byte)(length / 256));
+			b3[1] = ((byte)(length % 256));
+		}
+		else
+		{
+			b3[0] = 0;
+			b3[1] = ((byte)length);
+		}
+		return b3;
+	}
+
+	public static int getIntOnBit(int n, int offset, int length) {
+		return n >> 32 - offset - length & (-1 << length ^ 0xFFFFFFFF);
+	}
+
+	static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
+	public static final int BIT_1 = 1;
+	public static final int BIT_2 = 3;
+	public static final int BIT_3 = 7;
+	public static final int BIT_4 = 15;
+	public static final int BIT_5 = 31;
+	public static final int BIT_6 = 63;
+	public static final int BIT_7 = 127;
+	public static final int BIT_8 = 255;
+	public static final int BIT_9 = 511;
+	public static final int BIT_10 = 1023;
+	public static final int BIT_11 = 2047;
+	public static final int BIT_12 = 4095;
+	public static final int BIT_13 = 8191;
+	public static final int BIT_14 = 16383;
+	public static final int BIT_15 = 32767;
+	public static final int BIT_16 = 65535;
+
+	public static String bytesToHex(byte[] bytes, int bundleSize, char seperator)
+	{
+		char[] hexChars = new char[bytes.length * 2 + bytes.length / bundleSize];
+		int j = 0;
+		for (int k = 1; j < bytes.length; k++)
+		{
+			int v = bytes[j] & 0xFF;
+			int start = j * 2 + j / bundleSize;
+
+			hexChars[start] = HEX_ARRAY[(v >>> 4)];
+			hexChars[(start + 1)] = HEX_ARRAY[(v & 0xF)];
+			if (k % bundleSize == 0) {
+				hexChars[(start + 2)] = seperator;
+			}
+			j++;
+		}
+		return new String(hexChars).trim();
+	}
+
+	public static String bytesToHex(byte[] bytes, int bundleSize)
+	{
+		return bytesToHex(bytes, bundleSize, ' ');
+	}
+
+	public static String byteToHex(byte b)
+	{
+		String hexNumber = "0" + Integer.toHexString(0xFF & b).toUpperCase();
+		return hexNumber.substring(hexNumber.length() - 2);
+	}
+
+	public static int convertNotNullStringToInt(String data)
+	{
+		if (data == null || data.trim().length() == 0)
+			return 0;
+		return Long.valueOf(data).intValue();
+	}
+
+	public static double convertNotNullStringToDouble(String data)
+	{
+		if (data == null || data.trim().length() == 0)
+			return 0.0D;
+		return Double.valueOf(data).doubleValue();
+	}
+
+	public static String extractFilePath(String fullPath)
+	{
+		String resultPath = fullPath;
+		int lastPathIndex = resultPath.lastIndexOf("/") != -1 ? resultPath.lastIndexOf("/") : resultPath.lastIndexOf("\\");
+		return lastPathIndex != -1 ? resultPath.substring(0, lastPathIndex + 1) : resultPath;
+	}
+
+	public static String extractFileName(String fullPath)
+	{
+		String resultPath = fullPath;
+		int lastPathIndex = resultPath.lastIndexOf("/") != -1 ? resultPath.lastIndexOf("/") : resultPath.lastIndexOf("\\");
+		return lastPathIndex != -1 ? resultPath.substring(lastPathIndex + 1) : resultPath;
+	}
+
+	public static String lpad(String str, int len, String pad)
+	{
+		String result = str;
+		int templen = len - result.length();
+		for (int i = 0; i < templen; i++) {
+			result = pad + result;
+		}
+		return result;
+	}
+
+	public static int getBitField(byte b, int field)
+	{
+		return (b & 1 << field) > 0 ? 1 : 0;
+	}
+
+	public static int getBitField(byte b, int field, int count)
+	{
+		if (count == 1) {
+			count = 1;
+		} else if (count == 2) {
+			count = 3;
+		} else if (count == 3) {
+			count = 7;
+		} else if (count == 4) {
+			count = 15;
+		} else if (count == 5) {
+			count = 31;
+		} else if (count == 6) {
+			count = 63;
+		} else if (count == 7) {
+			count = 127;
+		} else if (count == 8) {
+			count = 255;
+		} else if (count == 9) {
+			count = 511;
+		} else if (count == 10) {
+			count = 1023;
+		} else if (count == 11) {
+			count = 2047;
+		} else if (count == 12) {
+			count = 4095;
+		} else if (count == 13) {
+			count = 8191;
+		} else if (count == 14) {
+			count = 16383;
+		} else if (count == 15) {
+			count = 32767;
+		} else if (count == 16) {
+			count = 65535;
+		}
+		return b >> field & count;
+	}
+
+	public static byte setBitField(byte b, int field, int value)
+	{
+		if ((value == 0) || (value == 1)) {
+			b = (byte)(b | value << field);
+		}
+		return b;
+	}
+
+	public static byte setBitField(byte b, int field, int count, int value)
+	{
+		if ((field + count <= 8) && (value < Math.pow(2.0D, count))) {
+			if (count == 1) {
+				count = 1;
+			} else if (count == 2) {
+				count = 3;
+			} else if (count == 3) {
+				count = 7;
+			} else if (count == 4) {
+				count = 15;
+			} else if (count == 5) {
+				count = 31;
+			} else if (count == 6) {
+				count = 63;
+			} else if (count == 7) {
+				count = 127;
+			} else if (count == 8) {
+				count = 255;
+			} else if (count == 9) {
+				count = 511;
+			} else if (count == 10) {
+				count = 1023;
+			} else if (count == 11) {
+				count = 2047;
+			} else if (count == 12) {
+				count = 4095;
+			} else if (count == 13) {
+				count = 8191;
+			} else if (count == 14) {
+				count = 16383;
+			} else if (count == 15) {
+				count = 32767;
+			} else if (count == 16) {
+				count = 65535;
+			}
+		}
+		b = (byte)(b & (count << field ^ 0xFFFFFFFF));
+		b = (byte)(b | (value & count) << field);
+
+		return b;
+	}
+}

+ 50 - 0
its-common/src/main/java/com/its/common/utils/Elapsed.java

@@ -0,0 +1,50 @@
+package com.its.common.utils;
+
+import java.util.concurrent.TimeUnit;
+
+public class Elapsed {
+
+	private long sTime = 0;
+
+	public Elapsed() {
+		reset();
+	}
+
+	private long getElapsed() {
+		return System.nanoTime() - sTime;
+	}
+	public long nanoSeconds() {
+		return getElapsed();
+	}
+
+	public long milliSeconds() {
+		return TimeUnit.MILLISECONDS.convert(getElapsed(), TimeUnit.NANOSECONDS);
+	}
+
+	public long seconds() {
+		return TimeUnit.SECONDS.convert(getElapsed(), TimeUnit.NANOSECONDS);
+	}
+	
+	public void reset() {
+		sTime = System.nanoTime();
+	}
+
+	public static String elapsedTimeStr(long elapsed) {
+		long seconds = TimeUnit.SECONDS.convert(elapsed, TimeUnit.NANOSECONDS);
+		long miliSeconds = TimeUnit.MILLISECONDS.convert(elapsed, TimeUnit.NANOSECONDS) % 1000;
+		long microSeconds = TimeUnit.MICROSECONDS.convert(elapsed, TimeUnit.NANOSECONDS) % 1000;
+		long nanoSeconds = TimeUnit.NANOSECONDS.convert(elapsed, TimeUnit.NANOSECONDS) % 1000;
+
+		if (seconds > 0) {
+			return String.format("Elapsed: %,d sec. %3d ms. %3d us. %3d ns.", seconds, miliSeconds, microSeconds, nanoSeconds);
+		}
+		if (miliSeconds > 0) {
+			return String.format("Elapsed: %3d ms. %3d us. %3d ns.", miliSeconds, microSeconds, nanoSeconds);
+		}
+		if (microSeconds > 0) {
+			return String.format("Elapsed: --- ms. %3d us. %3d ns.", microSeconds, nanoSeconds);
+		}
+		return String.format("Elapsed: --- ms. --- us. %3d ns.", nanoSeconds);
+	}
+
+}

+ 126 - 0
its-common/src/main/java/com/its/common/utils/NetUtils.java

@@ -0,0 +1,126 @@
+package com.its.common.utils;
+
+import java.net.*;
+import java.util.Enumeration;
+
+public class NetUtils {
+
+    private NetUtils() {}
+
+    public static String formatInetAddr(InetSocketAddress addr) {
+        InetAddress ia = addr.getAddress();
+
+        if (ia == null) {
+            return String.format("%s:%s", addr.getHostString(), addr.getPort());
+        }
+
+        if (ia instanceof Inet6Address) {
+            return String.format("[%s]:%s", ia.getHostAddress(), addr.getPort());
+        } else {
+            return String.format("%s:%s", ia.getHostAddress(), addr.getPort());
+        }
+    }
+
+    public static long ipToLong(String ipAddress) {
+        String[] ipAddressInArray = ipAddress.split("\\.");
+        long result = 0;
+        for (int i = 0; i < ipAddressInArray.length; i++) {
+            int power = 3 - i;
+            int ip = Integer.parseInt(ipAddressInArray[i]);
+            result += ip * Math.pow(256, power);
+        }
+        return result;
+    }
+
+    public static long ipToLong2(String ipAddress) {
+        long result = 0;
+        String[] ipAddressInArray = ipAddress.split("\\.");
+
+        for (int i = 3; i >= 0; i--) {
+            long ip = Long.parseLong(ipAddressInArray[3 - i]);
+            //left shifting 24,16,8,0 and bitwise OR
+            //1. 192 << 24
+            //1. 168 << 16
+            //1. 1   << 8
+            //1. 2   << 0
+            result |= ip << (i * 8);
+        }
+        return result;
+    }
+
+    public static String longToIp(long i) {
+
+        return ((i >> 24) & 0xFF) +
+                "." + ((i >> 16) & 0xFF) +
+                "." + ((i >> 8) & 0xFF) +
+                "." + (i & 0xFF);
+
+    }
+
+    public static String longToIp2(long ip) {
+        StringBuilder sb = new StringBuilder(15);
+
+        for (int i = 0; i < 4; i++) {
+            // 1. 2
+            // 2. 1
+            // 3. 168
+            // 4. 192
+            sb.insert(0, Long.toString(ip & 0xff));
+
+            if (i < 3) {
+                sb.insert(0, '.');
+            }
+            // 1. 192.168.1.2
+            // 2. 192.168.1
+            // 3. 192.168
+            // 4. 192
+            ip = ip >> 8;
+
+        }
+
+        return sb.toString();
+    }
+
+    public static String getLocalIp4Addr(){
+        String ipv4addr = null;
+        try {
+            Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
+            InetAddress ip = null;
+            while (allNetInterfaces.hasMoreElements()) {
+                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
+                Enumeration addresses = netInterface.getInetAddresses();
+                while (addresses.hasMoreElements()) {
+                    ip = (InetAddress) addresses.nextElement();
+                    if (ip != null && ip instanceof Inet4Address && !ip.isLoopbackAddress() &&ip.getHostAddress().indexOf(":")==-1) {
+                        ipv4addr = ip.getHostAddress();
+                    }
+                }
+            }
+        } catch (SocketException e) {
+            e.printStackTrace();
+        }
+        return ipv4addr;
+    }
+
+    public static String getHostAddress() {
+        String hostAddress;
+        try {
+            InetAddress localhost = InetAddress.getLocalHost();
+            hostAddress = localhost.getHostAddress();
+        } catch (UnknownHostException e) {
+            hostAddress = "127.0.0.1";
+        }
+        return hostAddress;
+    }
+
+    public static String getHostName() {
+        String hostName;
+        try {
+            InetAddress localhost = InetAddress.getLocalHost();
+            hostName = localhost.getHostName();
+        } catch (UnknownHostException e) {
+            hostName = "localhost";
+        }
+        return hostName;
+    }
+}

+ 10 - 0
its-common/src/main/java/com/its/common/utils/OsPlatform.java

@@ -0,0 +1,10 @@
+package com.its.common.utils;
+
+public class OsPlatform {
+    private OsPlatform() {}
+
+    private static final String OS = System.getProperty("os.name").toLowerCase();
+    public static boolean isWindows() {
+        return OS.contains("win");
+    }
+}

+ 44 - 0
its-common/src/main/java/com/its/common/utils/StringUtils.java

@@ -0,0 +1,44 @@
+package com.its.common.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public class StringUtils {
+
+    private StringUtils() {}
+
+    public static String getString(boolean value) {
+        return value ? "1" : "0";
+    }
+
+    public static List<String> splitEmpty(String value, String separator) {
+        List<String> results = new ArrayList<String>();
+        StringTokenizer stringTokenizer = new StringTokenizer(value, separator);
+        while (stringTokenizer.hasMoreTokens()) {
+            results.add(stringTokenizer.nextToken().trim());
+        }
+        return results;
+    }
+
+    public static List<String> split(String value, String separator) {
+        String[] splits = value.split(separator);
+        List<String> results = new ArrayList<String>();
+        for (int ii = 0; ii < splits.length; ii++) {
+            splits[ii] = splits[ii].trim();
+            if (!splits[ii].isEmpty()) {
+                results.add(splits[ii]);
+            }
+        }
+        return results;
+    }
+
+    public static boolean isEmpty(String str) {
+        return str == null || str.isEmpty();
+    }
+
+    public static boolean isBlank(String s) {
+        return s == null || s.trim().isEmpty();
+    }
+
+}

+ 10 - 0
its-common/src/main/java/com/its/common/utils/TestUtils.java

@@ -0,0 +1,10 @@
+package com.its.common.utils;
+
+public class TestUtils {
+
+	private TestUtils() {}
+
+	public static String run() {
+		return "TestUtils.run";
+	}
+}

+ 40 - 0
its-network/build.gradle

@@ -0,0 +1,40 @@
+plugins {
+    id 'java'
+}
+
+group = 'com.its'
+version = '0.0.1'
+
+sourceCompatibility = '1.8'
+targetCompatibility = '1.8'
+compileJava.options.encoding = 'UTF-8'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    implementation 'io.netty:netty-all:4.1.52.Final'
+}
+
+processResources {
+    enabled = false
+}
+
+jar {
+    enabled = true
+}
+
+test {
+    useJUnitPlatform()
+}
+
+task runInstallJarLibrary(type:Exec) {
+    doFirst {
+        println "its-network library install mvn repository..."
+        workingDir = file('.')
+        commandLine = ['cmd', '/C', 'start', 'install.bat']
+        // cmd /C start ./install.bat
+    }
+}
+jar.finalizedBy runInstallJarLibrary

+ 7 - 0
its-network/install.bat

@@ -0,0 +1,7 @@
+@echo off
+chcp 65001
+@echo on
+copy build\libs\its-network-0.0.1.jar c:\java\repository\
+cd C:\java\apache-maven-3.9.6\bin
+cd C:\Users\OpenValue\.m2\wrapper\dists\apache-maven-3.6.3-bin\1iopthnavndlasol9gbrbg6bf2\apache-maven-3.6.3\bin
+.\mvn install:install-file -Dfile="C:\java\repository\its-network-0.0.1.jar" -DgroupId=com.its -DartifactId=its-network -Dversion=0.0.1 -Dpackaging=jar -DlocalRepositoryPath=C:\java\repository\

+ 7 - 0
its-network/src/main/java/com/its/common/NetworkMain.java

@@ -0,0 +1,7 @@
+package com.its.common;
+
+public class NetworkMain {
+    public static void main(String[] args) {
+        System.out.printf("com.its.common.network!");
+    }
+}

+ 145 - 0
its-network/src/main/java/com/its/common/network/NettyUtils.java

@@ -0,0 +1,145 @@
+package com.its.common.network;
+
+import io.netty.channel.Channel;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.epoll.Epoll;
+import io.netty.channel.epoll.EpollEventLoopGroup;
+import io.netty.channel.epoll.EpollServerSocketChannel;
+import io.netty.channel.epoll.EpollSocketChannel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.ServerSocketChannel;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.util.concurrent.DefaultThreadFactory;
+
+import java.net.InetSocketAddress;
+
+public final class NettyUtils {
+
+    private NettyUtils() {}
+
+    public static String getAddress(Channel ch) {
+        String localIp = "local-unknown";
+        String remoteIp = "remote-unknown";
+        int localPort = 0;
+        int remotePort = 0;
+        InetSocketAddress localAddr = (InetSocketAddress)ch.localAddress();
+        if (localAddr != null) {
+            localIp = localAddr.getAddress().getHostAddress();
+            localPort = localAddr.getPort();
+        }
+
+        InetSocketAddress remoteAddr = (InetSocketAddress)ch.remoteAddress();
+        if (remoteAddr != null) {
+            remoteIp = remoteAddr.getAddress().getHostAddress();
+            remotePort = remoteAddr.getPort();
+        }
+        return "[Local #(" + localIp + ":" + localPort + ") Remote #(" + remoteIp + ":" + remotePort + ")]";
+    }
+
+    public static String getRemoteAddress(Channel ch) {
+        String ip = getRemoteIpAddress(ch);
+        int port = getRemotePort(ch);
+        return "[Remote #(" + ip + ":" + port + ")]";
+    }
+
+    public static String getLocalAddress(Channel ch) {
+        String ip = getLocalIpAddress(ch);
+        int port = getLocalPort(ch);
+        return "[Local #(" + ip + ":" + port + ")]";
+    }
+
+    public static String getRemoteIpAddress(Channel ch) {
+        String ip = "255.255.255.255";
+        InetSocketAddress inetAddr = (InetSocketAddress)ch.remoteAddress();
+        if (inetAddr != null) {
+            ip = inetAddr.getAddress().getHostAddress();
+        }
+        return ip;
+    }
+
+    public static long getRemoteIpAddressToLong(Channel ch) {
+        String[] ipAddressInArray = getRemoteIpAddress(ch).split("\\.");
+        long result = 0;
+        for (int i = 0; i < ipAddressInArray.length; i++) {
+            int power = 3 - i;
+            int ip = Integer.parseInt(ipAddressInArray[i]);
+            result += (long) (ip * Math.pow(256, power));
+        }
+        return result;
+    }
+
+    public static int getRemotePort(Channel ch) {
+        int port = 0;
+        InetSocketAddress inetAddr = (InetSocketAddress)ch.remoteAddress();
+        if (inetAddr != null) {
+            port = inetAddr.getPort();
+        }
+        return port;
+    }
+
+    public static String getLocalIpAddress(Channel ch) {
+        String ip = "127.0.0.1";
+        InetSocketAddress inetAddr = (InetSocketAddress)ch.localAddress();
+        if (inetAddr != null) {
+            ip = inetAddr.getAddress().getHostAddress();
+        }
+        return ip;
+    }
+    public static int getLocalPort(Channel ch) {
+        int port = 0;
+        InetSocketAddress inetAddr = (InetSocketAddress)ch.localAddress();
+        if (inetAddr != null) {
+            port = inetAddr.getPort();
+        }
+        return port;
+    }
+
+    public static boolean isEpollAvailable() {
+        // Netty epoll transport does not work with WSL (Windows Sybsystem for Linux) yet.
+/*
+        boolean HAS_WSLENV = System.getenv("WSLENV") != null;
+        return Epoll.isAvailable() && !HAS_WSLENV;
+*/
+        return Epoll.isAvailable();
+    }
+
+    public static EventLoopGroup newEventLoopGroup(int nThreads, String threadPoolName) {
+        if (isEpollAvailable()) {
+            if (threadPoolName.isEmpty()) {
+                return new EpollEventLoopGroup(nThreads);
+            }
+            else {
+                return new EpollEventLoopGroup(nThreads, new DefaultThreadFactory("epo"+threadPoolName));
+            }
+        }
+        else {
+            if (threadPoolName.isEmpty()) {
+                return new NioEventLoopGroup(nThreads);
+            }
+            else {
+                return new NioEventLoopGroup(nThreads, new DefaultThreadFactory("nio" + threadPoolName));
+            }
+        }
+    }
+
+    public static Class<? extends SocketChannel> getSocketChannel() {
+        if (isEpollAvailable()) {
+            return EpollSocketChannel.class;
+        }
+        else {
+            return NioSocketChannel.class;
+        }
+    }
+
+    public static Class<? extends ServerSocketChannel> getServerSocketChannel() {
+        if (isEpollAvailable()) {
+            return EpollServerSocketChannel.class;
+        }
+        else {
+            return NioServerSocketChannel.class;
+        }
+    }
+
+}

+ 63 - 0
its-network/src/main/java/com/its/common/network/tcp/server/NettyServerConfig.java

@@ -0,0 +1,63 @@
+package com.its.common.network.tcp.server;
+
+import lombok.Data;
+
+@Data
+public abstract class NettyServerConfig {
+
+    protected String bindingAddr = "";
+    protected int bindingPort = 9091;
+    protected int backlog = 0;
+    protected int acceptThreads = 0;
+    protected int workerThreads = 0;
+    protected int rcvBuf = 0;
+    protected int sndBuf = 0;
+    protected int readerIdleTimeSeconds = 0;
+    protected int writerIdleTimeSeconds = 0;
+    protected int allIdleTimeSeconds = 0;
+    protected int connectTimeoutSeconds = 0;
+
+    protected void configure() {
+/*
+        int MAX_CORE = Runtime.getRuntime().availableProcessors();
+        if (MAX_CORE < 8) {
+            MAX_CORE = 8;
+        }
+        int totalThreads = MAX_CORE * 2;
+*/
+        final int DEFAULT_EVENT_THREADS  = Runtime.getRuntime().availableProcessors() * 2;
+
+
+        if (this.bindingAddr.isEmpty()) {
+            this.bindingAddr = "0.0.0.0";
+        }
+        if (this.backlog == 0) {
+            this.backlog = 1024;
+        }
+        /*if (this.acceptThreads == 0) {
+            if (MAX_CORE <= 8) {
+                this.acceptThreads = 4;
+            } else if (MAX_CORE >= 32) {
+                this.acceptThreads = 12;
+            } else {
+                this.acceptThreads = 6;
+            }
+        }
+        if (this.workerThreads == 0) {
+            this.workerThreads = totalThreads - this.acceptThreads;
+        }*/
+        if (this.acceptThreads == 0) {
+            this.acceptThreads = DEFAULT_EVENT_THREADS;
+        }
+        if (this.workerThreads == 0) {
+            this.workerThreads = DEFAULT_EVENT_THREADS;
+        }
+
+        if (this.rcvBuf == 0) {
+            this.rcvBuf = Short.MAX_VALUE / 2;
+        }
+        if (this.sndBuf == 0) {
+            this.sndBuf = Short.MAX_VALUE / 2;
+        }
+    }
+}

+ 80 - 0
its-network/src/main/java/com/its/common/network/tcp/server/NettyTcpServer.java

@@ -0,0 +1,80 @@
+package com.its.common.network.tcp.server;
+
+import com.its.common.network.NettyUtils;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.EventLoopGroup;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Data
+public abstract class NettyTcpServer {
+
+    private final NettyServerConfig config;
+
+    private EventLoopGroup acceptGroups = null;
+    private EventLoopGroup workerGroups = null;
+    private ServerBootstrap serverBootstrap = null;
+    private ChannelFuture channelFuture = null;
+
+    private ChannelInitializer<Channel> channelInitializer;
+
+    public NettyTcpServer(NettyServerConfig config) {
+        this.config = config;
+    }
+
+    public void run() {
+
+        try {
+            if (NettyUtils.isEpollAvailable()) {
+                log.info("서버가 리눅스 EPOLL 모드에서 실행됩니다.");
+            }
+            else {
+                log.info("서버가 윈도우 NIO 모드에서 실행됩니다.");
+            }
+
+            this.serverBootstrap = ServerBootstrapFactory.createBootstrap(this.config, this.channelInitializer);
+
+        } catch (Exception e) {
+            log.error("run exception: {}", e.toString());
+        }
+
+        log.info("================================================");
+        log.info("          bindAddress: {}", this.config.getBindingAddr());
+        log.info("             bindPort: {}", this.config.getBindingPort());
+        log.info("              backlog: {}", this.config.getBacklog());
+        log.info("        acceptThreads: {}", this.config.getAcceptThreads());
+        log.info("        workerThreads: {}", this.config.getWorkerThreads());
+        log.info("readerIdleTimeSeconds: {}", this.config.getReaderIdleTimeSeconds());
+        log.info("================================================");
+
+        try {
+            if (this.config.getBindingAddr().equals("0.0.0.0")) {
+                this.channelFuture = this.serverBootstrap.bind(this.config.getBindingPort());
+            }
+            else {
+                this.channelFuture = this.serverBootstrap.bind(this.config.getBindingAddr(), config.getBindingPort());
+            }
+        }
+        catch (Exception e) {
+            log.error("{}", e.toString());
+            this.acceptGroups.shutdownGracefully();
+            this.workerGroups.shutdownGracefully();
+        }
+    }
+
+    public void stop() {
+        try {
+            this.acceptGroups.shutdownGracefully().sync();
+            this.workerGroups.shutdownGracefully().sync();
+            this.channelFuture.channel().closeFuture().sync();
+        }
+        catch (InterruptedException e) {
+            log.error("{}", e.toString());
+            Thread.currentThread().interrupt();
+        }
+    }
+}

+ 35 - 0
its-network/src/main/java/com/its/common/network/tcp/server/ServerBootstrapFactory.java

@@ -0,0 +1,35 @@
+package com.its.common.network.tcp.server;
+
+import com.its.common.network.NettyUtils;
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.*;
+
+public class ServerBootstrapFactory {
+
+    private ServerBootstrapFactory() {}
+    
+    public static ServerBootstrap createBootstrap(NettyServerConfig config, ChannelInitializer<Channel> channelInitializer) throws Exception {
+        ServerBootstrap serverBootstrap = new ServerBootstrap();
+        EventLoopGroup acceptGroups;
+        EventLoopGroup workerGroups;
+
+        acceptGroups = NettyUtils.newEventLoopGroup(config.getAcceptThreads(), "Accept");
+        workerGroups = NettyUtils.newEventLoopGroup(config.getWorkerThreads(), "Worker");
+        serverBootstrap.channel(NettyUtils.getServerSocketChannel());
+        serverBootstrap.group(acceptGroups, workerGroups);
+
+        serverBootstrap.option(ChannelOption.AUTO_READ, true);
+        serverBootstrap.option(ChannelOption.SO_BACKLOG, config.getBacklog());
+        serverBootstrap.option(ChannelOption.SO_RCVBUF, config.getRcvBuf());
+        serverBootstrap.option(ChannelOption.SO_REUSEADDR, true);
+        serverBootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, config.getConnectTimeoutSeconds()*1000);
+
+        serverBootstrap.childOption(ChannelOption.SO_LINGER, 0);           // 4way-handshake 비활성
+        serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, false);    // KEEPALIVE 비활성(활성: true)
+        serverBootstrap.childOption(ChannelOption.SO_REUSEADDR, true);     // 소켓 재사용
+        serverBootstrap.childOption(ChannelOption.TCP_NODELAY, true);      // Nagle 알고리즘 비활성화
+        serverBootstrap.childHandler(channelInitializer);
+
+        return serverBootstrap;
+    }
+}

+ 39 - 0
its-spring/build.gradle

@@ -0,0 +1,39 @@
+plugins {
+    id 'java'
+}
+
+group = 'com.its'
+version = '0.0.1'
+
+sourceCompatibility = '1.8'
+targetCompatibility = '1.8'
+compileJava.options.encoding = 'UTF-8'
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+}
+
+processResources {
+    enabled = false
+}
+
+jar {
+    enabled = true
+}
+
+test {
+    useJUnitPlatform()
+}
+
+task runInstallJarLibrary(type:Exec) {
+    doFirst {
+        println "its-spring library install mvn repository..."
+        workingDir = file('.')
+        commandLine = ['cmd', '/C', 'start', 'install.bat']
+        // cmd /C start ./install.bat
+    }
+}
+jar.finalizedBy runInstallJarLibrary

+ 7 - 0
its-spring/install.bat

@@ -0,0 +1,7 @@
+@echo off
+chcp 65001
+@echo on
+copy build\libs\its-spring-0.0.1.jar c:\java\repository\
+cd C:\java\apache-maven-3.9.6\bin
+cd C:\Users\OpenValue\.m2\wrapper\dists\apache-maven-3.6.3-bin\1iopthnavndlasol9gbrbg6bf2\apache-maven-3.6.3\bin
+.\mvn install:install-file -Dfile="C:\java\repository\its-spring-0.0.1.jar" -DgroupId=com.its -DartifactId=its-spring -Dversion=0.0.1 -Dpackaging=jar -DlocalRepositoryPath=C:\java\repository\

+ 7 - 0
its-spring/src/main/java/com/its/common/SpringMain.java

@@ -0,0 +1,7 @@
+package com.its.common;
+
+public class SpringMain {
+    public static void main(String[] args) {
+        System.out.printf("com.its.common.spring!");
+    }
+}

+ 36 - 0
its-spring/src/main/java/com/its/common/spring/SpringUtils.java

@@ -0,0 +1,36 @@
+package com.its.common.spring;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SpringUtils implements ApplicationContextAware {
+    private static ApplicationContext applicationContext;
+//    private static String applicationId;
+//    private static Environment environment;
+
+    @Override
+    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
+        applicationContext = ctx;
+//        applicationId = ctx.getId();
+//        environment = ctx.getEnvironment();
+    }
+
+    public static Object getBean(String name){
+        return applicationContext.getBean(name);
+    }
+
+    public static <T> T getBean(Class<T> clazz){
+        return applicationContext.getBean(clazz);
+    }
+
+    public static <T> T getBean(String name, Class<T> clazz){
+        return applicationContext.getBean(name, clazz);
+    }
+
+    public static String[] getAllDefinitionBeanName() {
+        return applicationContext.getBeanDefinitionNames();
+    }
+}

+ 5 - 0
settings.gradle

@@ -0,0 +1,5 @@
+rootProject.name = 'its-library'
+include 'its-common'
+include 'its-spring'
+include 'its-network'
+